Соединение с сервером DB2 потеряно при выполнении выбора внутри сценария оболочки - PullRequest
1 голос
/ 13 марта 2019

Я пытаюсь автоматизировать некоторые проверки ограничений после огромного импорта данных, и я столкнулся с текущей проблемой. Я нашел обходной путь, который я также опишу, но если есть кто-то, кто лучше меня знает Linux и может объяснить, почему это происходит, я был бы очень признателен.

Так что, если я выполняю следующие команды из DB2 CLI после того, как я вошел в систему как владелец экземпляра, я получу выводимое значение без каких-либо ошибок.

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

Если я сохраняю команды в файле select.sh и вызываю скрипт в том же процессе, используя . select.sh после входа в систему как владелец экземпляра, я получаю сообщение об ошибке, что нет соединения с базой данных. Я думаю, что каким-то образом подстановка команд выполняется в новом потоке, где соединение с сервером не переадресовано.

select.sh content:

VAL = $ (db2 -x 'выберите количество (*) из SCHEMA.TABLE')

значение эха = $ VAL

Как я запускаю скрипт:

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:~>

Если select.sh содержит только команду db2, без назначения VAL соединение не будет потеряно:

select.sh content:

db2 -x 'выберите количество (*) из SIM.SUPPLIER'

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

А теперь обходной путь: Запись SQL select в файл и вызов файла внутри select.sh делает трюк, и соединение не теряется.

select.sh content

echo 'выберите количество (*) из SIM.SUPPLIER;' > sql

db2 -txf sql

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

Но это не работает, и я не понимаю, почему:

echo 'выберите количество (*) из SIM.SUPPLIER;' > sql

echo $ (db2 -txf sql)

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

Так может кто-нибудь объяснить мне, почему подстановка команд теряет соединение с сервером и как я все еще могу его использовать, но сохранить соединение с сервером.

PS: мне не разрешено подключаться к серверу внутри любых скриптов. Из-за соображений безопасности внутри файлов не должно быть никаких учетных данных. Соединение с сервером должно быть установлено до вызова других сценариев и только один раз.

Спасибо

Ответы [ 3 ]

1 голос
/ 13 марта 2019

Причина заключается в том, что каждый из VAL=$(....) и echo $(db2 -txf sql) запускает подоболочку, и в этом подоболочке нет соединения с базой данных. Ваш обходной путь не требует подоболочки, поэтому он работает.

Для bash: если вам не разрешено иметь connect внутри ваших скриптов, вы должны избегать подоболочек для Db2 CLP, как вы это делаете с обходным решением.

Вы можете использовать временные файлы, чтобы избежать подоболочек, за счет большего разбора и т. Д. Например, вместо использования VAL=$(db2 ...) используйте db2 ... > $tmpfile с последующим VAL=$(cat $tmpfile) или подобной техникой.

Вы не можете «переслать соединение» как таковое.

Если вы можете использовать ksh93 с сопроцессами, вы можете обмениваться данными между процессами и гарантировать, что все действия db2 CLP выполняются в одной задаче, которая затем направляет результаты в другую задачу. Но такая сложность редко стоит, и может быть предпочтительнее использовать другой язык сценариев без оболочки.

0 голосов
/ 13 марта 2019

Это зависит от оболочки.
bash открывает вложенную оболочку, которая не имеет связи с фоновым процессом db2 (db2bp), которая содержит соединение с базой данных.

Попробуйте ksh. Он не должен открывать вложенную оболочку. Если вы используете нотацию dot space file, для родительского сеанса должен быть установлен ksh:

$ ksh
$ db2 connect to mydb ...
$ . ./select.sh
0 голосов
/ 13 марта 2019

См. Информацию о внешних и внутренних процессах и примеры для команды Db2 . По сути, команда db2 имеет пользовательский интерфейс (внешний интерфейс) и связанный внутренний процесс (соединение с базой данных, контекст и т. Д.). Когда вы вызываете сценарий и непосредственно выполняете db2, он может подключиться к внутреннему процессу, который поддерживает соединение с базой данных.

Когда вы выполняете команду в скобках, (db2 ...), появляется новый подпроцесс (подоболочка). Это другая среда, в которой нет информации о внутреннем процессе и, следовательно, о соединении с базой данных Db2.

...