1
votes

Connexion au serveur DB2 perdue lors de l'exécution d'une sélection dans un script shell

J'essaie d'automatiser certaines vérifications de contraintes après une énorme importation de données et j'ai rencontré le problème de fluidité. J'ai trouvé une solution de contournement que je vais également décrire, mais s'il y a quelqu'un qui a une meilleure connaissance de Linux que moi et peut expliquer pourquoi cela se produit, je l'apprécierais vraiment.

Donc, si j'exécute les commandes suivantes à partir de DB2 CLI après avoir été connecté en tant que propriétaire de l'instance, je reçois la valeur de sortie imprimée, sans aucune erreur.

bla:~/> . select.sh
SQL1024N A database connection does not exist. SQLSTATE=08003
bla:~/>

Si j'enregistre les commandes dans un fichier select.sh et que j'appelle le script dans le même processus en utilisant . select.sh après avoir été connecté en tant que propriétaire de l'instance, j'obtiens un message d'erreur indiquant qu'il n'y a pas de connexion à la base de données. Je pense que d'une manière ou d'une autre, la substitution de commande s'exécute dans un nouveau thread où la connexion au serveur n'est pas transmise.

select.sh content:

VAL = $ (db2 -x 'select count (*) from SCHEMA.TABLE')

valeur d'écho = $ VAL

Comment j'exécute le script:

bla:~> . select.sh
     621684
bla:~>

Si select.sh contient uniquement la commande db2, sans l'affectation à VAL, la connexion ne l'est pas perdu:

contenu select.sh:

db2 -x 'select count (*) from SIM.SUPPLIER'

bla:~> . select.sh
     621684
bla:~>

Et maintenant la solution de contournement: Écrire la sélection SQL dans un fichier et appeler le fichier à l'intérieur de select.sh fait l'affaire et la connexion n'est pas perdue.

select.sh content

echo 'select count (*) from SIM.SUPPLIER;' > sql

db2 -txf sql

bla:~> db2 connect to DB

   Database Connection Information

 Database server        = DB2/LINUXX8664 11.1.0
 SQL authorization ID   = DB2INS10
 Local database alias   = DB

bla:~> . select.sh
value = SQL1024N A database connection does not exist. SQLSTATE=08003
bla:~>

Mais cela ne fonctionne pas, et je ne comprends pas pourquoi:

echo 'select count (*) from SIM.SUPPLIER;' > sql

echo $ (db2 -txf sql)

bla:~> VAL=$(db2 -x 'select count(*) from SIM.SUPPLIER')
bla:~> echo value = $VAL
value = 621684

Quelqu'un peut-il donc m'expliquer pourquoi la substitution de commande perd la connexion au serveur et comment puis-je toujours l'utiliser tout en conservant la connexion au serveur.

PS: Je ne suis pas autorisé à me connecter au serveur dans aucun script. Aucune information d'identification ne doit être écrite à l'intérieur des fichiers pour des raisons de sécurité. La connexion au serveur doit être établie avant d'appeler d'autres scripts et une seule fois.

Merci


0 commentaires

3 Réponses :


1
votes

La raison en est que le VAL = $ (....) et le echo $ (db2 -txf sql) exécutent chacun un sous-shell, et en cela sous-shell il n'y a pas de connexion à la base de données. Votre solution de contournement n'implique pas de sous-shell, donc cela fonctionne.

Pour bash, si vous ne pouvez pas avoir une connexion dans vos scripts, vous devez éviter le sous-shelling pour le Db2 CLP, comme vous le faites avec votre solution de contournement.

Vous pouvez utiliser des fichiers temporaires pour éviter les sous-shell, au prix d'une analyse plus poussée, etc. Par exemple, au lieu d'utiliser VAL = $ (db2 ...) , utilisez db2 ...> $ tmpfile suivi de VAL = $ (cat $ tmpfile) ou d'une technique similaire.

Vous ne pouvez pas «transférer la connexion» en tant que telle.

Si vous pouvez utiliser ksh93 avec des coprocessus, vous pouvez alors communiquer entre les processus et vous assurer que toutes les actions db2 CLP se produisent dans une tâche qui redirige ensuite les résultats vers une autre tâche. Mais une telle complexité vaut rarement la peine et il peut être préférable d'utiliser un autre langage de script non-shell.


1 commentaires

C'était aussi mon impression, mais comment puis-je le forcer à fonctionner dans le même shell, sans sous-shell, ou comment transférer la connexion?



0
votes

Voir le des informations sur les processus front-end et back-end et les exemples de la commande Db2 . Essentiellement, la commande db2 a l'interface utilisateur (front-end) et un processus back-end associé (connexion à la base de données, contexte, etc.). Lorsque vous appelez le script et exécutez directement db2 , il est capable de se connecter au processus back-end qui contient la connexion à la base de données.

Lorsque vous exécutez la commande entre parenthèses, (db2 ...) , un nouveau sous-processus (sous-shell) est généré. Il s'agit d'un environnement différent et ne dispose pas d'informations sur le processus back-end, et donc sur la connexion à la base de données Db2.


0 commentaires

0
votes

Cela dépend du shell.
bash ouvre un sous-shell, qui n'a pas de connexion à votre processus d'arrière-plan db2 ( db2bp ), qui contient la connexion à la base de données.

Essayez ksh. Il ne devrait pas ouvrir un sous-shell. Si vous utilisez une notation dot space file , ksh doit être défini pour votre session parent:

$ ksh
$ db2 connect to mydb ...
$ . ./select.sh


0 commentaires