1
votes

DB2 CLP transmettant une variable dans un fichier .sql

Comme mon script shell appelle Db2 plusieurs fois avec une instruction SQL ultra longue, j'aimerais extraire les instructions SQL du script et les mettre dans un fichier .sql , puis l'exécuter à partir de le processeur de ligne de commande Db2 db2 -f xxx.sql .

Je veux que certaines des instructions SQL utilisent des variables qui sont transmises à partir du script shell.

Y a-t-il toute méthode comme sqlplus d'Oracle qui peut passer des variables à l'intérieur du fichier .sql par '& 1'?

DB21004E  You cannot specify both an input file and a command when invoking
the Command Line Processor.

Cela renvoie une erreur DB21004E:

xxx.sql
SELECT * FROM TABLE_A WHERE FIELD_B > &1

CLP
db2 -f xxx.sql 999


0 commentaires

3 Réponses :


0
votes

Le CLP db2 sous Linux / Unix / Windows ne prend pas en charge les paramètres substituables, ce qu'IBM a omis il y a longtemps.

Vous pouvez envisager l'une de ces options:

  • Utilisez le clpplus outil au lieu du CLP db2 pour exécuter des scripts. Il émule certaines des fonctionnalités d'Oracle SQL * plus, y compris la possibilité de transmettre des paramètres de position sur la ligne de commande et de les référencer comme & 1 et & 2 etc. dans vos scripts. Cependant, les scripts doivent alors utiliser la syntaxe de style Oracle, bien que votre serveur Db2 n'ait pas besoin de la compatibilité Oracle. Vous bénéficiez également d'un meilleur contrôle de mise en forme sur la sortie de la requête.

  • Déplacez la logique de requête dans les routines de la ou des bases de données et appelez-les avec des paramètres dans vos scripts. Par exemple, appelez les requêtes en tant que procédures stockées avec des paramètres d'entrée.

  • générez dynamiquement vos scripts SQL avec les paramètres appropriés et continuez à les exécuter avec le CLP db2 . En fait, vous faites votre propre substitution de variable, possible via des outils comme awk et sed ou similaire.


0 commentaires

2
votes

A variable globale de session peut être initialisée et référencée par différentes instructions et scripts SQL qui s'exécutent dans le même descripteur de session / connexion Db2. Il s'agit d'une fonctionnalité SQL Db2 qui fonctionnera dans CLP, clpplus, les procédures stockées, les blocs SQL en ligne / composés et tout langage de programmation avec un pilote client Db2.

La variable elle-même est un objet permanent dans la base de données et n'a besoin que de être créé une fois. Son nom et son type de données seront visibles par tous les utilisateurs autorisés dans la base de données, mais la valeur stockée dans la variable est privée pour chaque connexion.

Commencez par créer la variable. Cela ne doit être fait qu'une seule fois.

db2 "CONNECT TO DBNAME"
db2 "SET UTIL.FIELDBMINVALUE = 999"
db2 -f xxx.sql
db2 "CONNECT RESET"
db2 "TERMINATE"

Dans votre script SQL, faites référence à la variable au lieu d'une valeur littérale. Le script ne peut contenir aucune instruction CONNECT car cela détruirait la session en cours.

-- xxx.sql
SELECT * FROM TABLE_A WHERE FIELD_B > UTIL.FIELDBMINVALUE

Avant d'exécuter le script SQL, connectez-vous à la base de données et initialisez le variable.

db2 "CONNECT TO DBNAME"
db2 "CREATE VARIABLE UTIL.FIELDBMINVALUE INTEGER"


0 commentaires

0
votes

Merci à toutes les réponses ci-dessus.

Voici ma méthode pour générer dynamiquement le SQL à partir du fichier .sql par envsubst . Ceci est très similaire au fichier d'origine oracle .sql . Il suffit de changer & N en $varN .

#Script
send_xxx_sql_file () {
var_string=$(for i in $(seq $#); do echo -e "var$i=\${$i} \c"; done)
SQL_statement=$(eval "$var_string envsubst < xxx.sql " | sed '/^--/d' | tr "\n" " " | tr -s " ")
db2 "$SQL_statement"
}

send_xxx_sql_file 999 111
--xxx.sql
--$var1 : field B remark
--$var2 : field C remark

SELECT * FROM TABLE_A 
    WHERE FIELD_B > $var1
    AND   FIELD_C = $var2 ;

var_string devient var1 = $ {1} var2 = $ {2}

SQL_statement devient SELECT * FROM TABLE_A WHERE FIELD_B> 999 AND FIELD_C = 111;

sed '/ ^ - / d' supprimer les lignes précédées de --

tr "\ n" "" remplacer la nouvelle ligne par un espace

tr -s "" remplacer la séquence d'espaces répétés en 1 espace p>


0 commentaires