【问题标题】:Can I call a global variable in source variable in ODI?我可以在 ODI 的源变量中调用全局变量吗?
【发布时间】:2017-07-21 00:06:23
【问题描述】:

我正在尝试构建一个 ODI 过程,它将从 oracle 数据库元数据表中获取模式名称、数据库过程名称和参数。参数字段包含一个ODI全局变量的名称。source命令是这样的

SELECT SCHEMA_NAME VAR_SCHEMA, PROCEDURE_NAME VAR_PROCEDURE, PARAMETER_NAME 
VAR_PARAMETER FROM SCHEMA-NAME.TABLE_NAME

source 命令的输出是这样的:

VAR_SCHEMA_NAME  VAR_TABLE_NAME   VAR_PARAMETER
ABC              PROC_LIST        TO_DATE('#VAR_ETL_LOAD_DATE','DD/MM/RRRR') 

这里,#VAR_ETL_LOAD_DATE 是 ODI 中的全局变量。

在过程的目标命令中,我想使用源命令中的这些信息来执行元数据表中列出的过程。我写了一个这样的命令:

DECLARE

VVC_SQL_STMT LONG;

BEGIN

VVC_SQL_STMT := 'BEGIN
            #VAR_SCHEMA_NAME.#VAR_PROCEDURE_NAME(#VAR_PARAMETER);
            END;';                                                     

INSERT INTO AK_TST2 VALUES(VVC_SQL_STMT,SYSDATE);

COMMIT;

EXECUTE IMMEDIATE (VVC_SQL_STMT);

END;

此代码在 ODI 中给出以下错误:

ODI-1228: Task PROC_SP_HANDLER (Procedure) fails on the target ORACLE 
connection OCDM_SYS.
Caused By: java.sql.SQLException: ORA-06550: line 8, column 61:
PLS-00103: Encountered the symbol "#" when expecting one of the following:

* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset

这是什么原因?如何通过从元数据表中读取过程名称和参数在 ODI 中执行存储过程?

【问题讨论】:

    标签: sql oracle oracle-data-integrator


    【解决方案1】:

    如果您从表中选择数据并将结果用作进一步执行的代码,通常您不能在那里使用 ODI 变量。因为 ODI 识别它是一个变量并用一个变量替换它为时已晚。这对于全局变量和项目变量都是一样的。

    如果您可以从 ?- 或 %-substitution 打印 "#"+variable_name,那么它将起作用。但是,如果 @-substitution 打印变量名,或者变量在从 Source 获取值后显示为最终代码,则为时已晚。在这种情况下,它仍然是纯文本#VAR

    在您的特定情况下,您可以执行以下操作:

    1. 在包中声明所有变量,如#VAR_ETL_LOAD_DATE。我的意思是所有可能出现在元数据表中的变量。因为场景应该提前知道所有变量。
    2. 使用 odiRef.getJDBCConnection('SRC') 在 ?-substitution 中选择和获取记录。将所有结果以可执行代码的形式收集到一个 java 变量中。

    例如,源代码可能如下所示:

    select 1 from dual;
    <? 
    import java.sql.*;
    String crlf = System.getProperty("line.separator");
    String result = "begin"+crlf+"null;"+crlf;
    PreparedStatement stmt = odiRef.getJDBCConnection("SRC").prepareStatement("select schema||'.'||proc||'('||param||')' from metatable");
    ResultSet rs = stmt.executeQuery();
    while(rs.next()){
      result += "insert into ak_tst2 values('"+rs.getString(1).replaceAll("'",'"'.toString())+"');"+crlf;
      result += "commit;"+crlf;
      result += rs.getString(1)+";"+crlf;
    }
    result += "end;";
    rs.close();
    stmt.close();
    ?>
    

    目标代码应该很简单

    <?=result?>
    

    在运行时目标代码会这样显示

    begin
    null;
    insert into ak_tst2 values('qwe.asd("param_using_#var")');
    commit;
    qwe.asd('param_using_#var');
    insert into ak_tst2 values('qwe2.asd2("param2_using_#var")');
    commit;
    qwe2.asd2('param2_using_#var');
    insert into ak_tst2 values('qwe3.asd3("param3_using_#var")');
    commit;
    qwe3.asd3('param3_using_#var');
    end;
    

    ODI 变量将被成功替换为值。

    【讨论】:

      猜你喜欢
      • 2014-03-14
      • 1970-01-01
      • 2017-04-26
      • 2019-10-30
      • 1970-01-01
      • 2022-07-04
      • 2011-01-21
      • 2017-07-11
      • 1970-01-01
      相关资源
      最近更新 更多