我可以在 ODI 的源变量中调用全局变量吗?
Can I call a global variable in source variable in ODI?
我正在尝试构建一个 ODI 过程,它将从 Oracle 数据库元数据中获取模式名称、数据库过程名称和参数 table。参数字段包含一个 ODI global 的名称 variable.The source command is like this
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中的一个全局变量。
在程序的目标命令中,我想使用来自源命令的这些信息来执行元数据table中列出的程序。我写了这样的命令:
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 中执行存储过程table?
如果您 select 来自 table 的数据并将结果用作进一步执行的代码,通常您不能在那里使用 ODI 变量。因为 ODI 来不及认识到它是一个变量并用一个变量代替它。这对于全局变量和项目变量都是一样的。
如果您可以从 ?- 或 %-substitution 打印 "#"+variable_name
,那么它将起作用。但是,如果 @-substitution 打印变量名,或者变量在从 Source 获取值后显示为最终代码,则为时已晚。在这种情况下,它仍然是纯文本 #VAR
.
在您的特定情况下,您可以执行以下操作:
- 像
#VAR_ETL_LOAD_DATE
一样在包中声明所有变量。我的意思是所有可能出现在元数据中的变量 table。因为场景应该提前知道所有变量。
- Select 并使用 odiRef.getJDBCConnection('SRC') 在 ?-替换中获取记录。将所有结果以 executable 代码的形式收集到一个 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变量将被值成功替换。
我正在尝试构建一个 ODI 过程,它将从 Oracle 数据库元数据中获取模式名称、数据库过程名称和参数 table。参数字段包含一个 ODI global 的名称 variable.The source command is like this
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中的一个全局变量。
在程序的目标命令中,我想使用来自源命令的这些信息来执行元数据table中列出的程序。我写了这样的命令:
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 中执行存储过程table?
如果您 select 来自 table 的数据并将结果用作进一步执行的代码,通常您不能在那里使用 ODI 变量。因为 ODI 来不及认识到它是一个变量并用一个变量代替它。这对于全局变量和项目变量都是一样的。
如果您可以从 ?- 或 %-substitution 打印 "#"+variable_name
,那么它将起作用。但是,如果 @-substitution 打印变量名,或者变量在从 Source 获取值后显示为最终代码,则为时已晚。在这种情况下,它仍然是纯文本 #VAR
.
在您的特定情况下,您可以执行以下操作:
- 像
#VAR_ETL_LOAD_DATE
一样在包中声明所有变量。我的意思是所有可能出现在元数据中的变量 table。因为场景应该提前知道所有变量。 - Select 并使用 odiRef.getJDBCConnection('SRC') 在 ?-替换中获取记录。将所有结果以 executable 代码的形式收集到一个 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变量将被值成功替换。