2017-05-22 7 views
2

J'essaye de construire une procédure d'ODI, qui prendra le nom de schéma, le nom de procédure de DB et les paramètres d'une table de métadonnées de base de données d'oracle. Le champ de paramètre contient le nom d'une commande globale ODI source variable.Appareil est comme cePuis-je appeler une variable globale dans la variable source dans ODI?

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

la sortie de la commande source est comme ceci:

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

Ici, #VAR_ETL_LOAD_DATE est une variable globale en ODI.

Dans la commande cible de la procédure, je souhaite utiliser ces informations provenant de la commande source pour exécuter les procédures répertoriées dans la table de métadonnées. J'ai écrit une commande comme ceci:

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; 

Ce code donne l'erreur suivante dans 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 

Quelle est les raisons de cela et comment puis-je exécuter des procédures stockées dans ODI en lisant les noms de procédure et paramètres d'une table de métadonnées?

Répondre

0

Si vous sélectionnez des données dans une table et que vous utilisez le résultat comme code pour une exécution ultérieure, vous ne pouvez normalement pas utiliser de variables ODI. Parce qu'il est trop tard pour ODI de reconnaître que c'est une variable et de la substituer par une variable. C'est la même chose pour les variables globales et de projet.

Si vous pouviez imprimer "#"+variable_name de? - ou% -substitution que cela fonctionnera. Mais si @ -substitution affiche le nom de la variable ou si la variable apparaît comme un code final après avoir récupéré les valeurs de Source, il est trop tard. Dans ce cas, il reste en texte brut #VAR.

Dans votre cas particulier, vous pouvez effectuer les opérations suivantes:

  1. Déclarez toutes les variables telles que #VAR_ETL_LOAD_DATE dans un paquet. Je veux dire toutes les variables qui pourraient potentiellement apparaître dans la table de métadonnées. Le scénario de Bacause devrait connaître toutes les variables à l'avance.
  2. Sélectionnez et récupérez les enregistrements dans? -substitution à l'aide de odiRef.getJDBCConnection ('SRC'). Collecter tous les résultats dans une variable java sous la forme de code exécutable.

Par exemple, le code source pourrait ressembler à ceci:

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(); 
?> 

code cible doit être très simple

<?=result?> 

Au code cible d'exécution apparaît comme celui-ci

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; 

Et les variables ODI seront remplacées avec succès par la valeur s.