#sql #linux #shell #db2 #sh
#sql #linux #оболочка #db2 #ш #sh
Вопрос:
Я пытаюсь автоматизировать некоторые проверки ограничений после огромного импорта данных, и я столкнулся с текущей проблемой. Я нашел обходной путь, который я также опишу, но если есть кто-то, кто лучше меня разбирается в Linux и может объяснить, почему это происходит, я был бы очень признателен.
Итак, если я выполняю следующие команды из командной строки DB2 CLI после входа в систему в качестве владельца экземпляра, я получаю выводимое значение, напечатанное без каких-либо ошибок.
bla:~> VAL=$(db2 -x 'select count(*) from SIM.SUPPLIER')
bla:~> echo value = $VAL
value = 621684
Если я сохраню команды в select.sh файл и вызов скрипта в том же процессе, используя . select.sh
после входа в систему в качестве владельца экземпляра, я получаю сообщение об ошибке, что нет подключения к базе данных.
Я думаю, что каким-то образом замена команды выполняется в новом потоке, где соединение с сервером не пересылается.
select.sh содержимое:
VAL=$(db2 -x ‘количество выбранных(*) из СХЕМЫ.ТАБЛИЦА’)
значение echo = $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 содержимое:
db2 -x ‘количество выбранных(*) из SIM.SUPPLIER’
bla:~> . select.sh
621684
bla:~>
И теперь обходной путь:
Запись SQL select в файл и вызов running файла внутри select.sh выполняется трюк, и соединение не теряется.
select.sh содержимое
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: Мне не разрешено подключаться к серверу внутри каких-либо скриптов. Никакие учетные данные не должны записываться внутри файлов по соображениям безопасности. Соединение с сервером должно быть установлено перед вызовом других скриптов и только один раз.
Спасибо
Ответ №1:
Причина в том, что VAL=$(....)
и echo $(db2 -txf sql)
каждый запускает подоболочку, и в этой подоболочке нет подключения к базе данных. Ваш обходной путь не включает подоболочку, поэтому он работает.
Для bash, если вам запрещено иметь connect
внутри ваших скриптов, тогда вы должны избегать дополнительной обработки для Db2 CLP, как вы делаете с вашим обходным путем.
Вы можете использовать временные файлы, чтобы избежать вложенных оболочек, за счет дополнительного синтаксического анализа и т.д. Например, вместо использования VAL=$(db2 ...)
используйте db2 ... > $tmpfile
с последующим VAL=$(cat $tmpfile)
использованием или аналогичную технику.
Вы не можете «переслать соединение» как таковое.
Если вы можете использовать ksh93 с сопроцессами, то вы можете обмениваться данными между процессами и гарантировать, что все действия db2 CLP выполняются в одной задаче, которая затем передает результаты в другую задачу. Но такая сложность редко бывает целесообразной, и может быть предпочтительнее использовать другой язык сценариев, отличный от shell.
Комментарии:
1. У меня тоже сложилось такое впечатление, но как я могу заставить его запускаться в той же оболочке, без вложенной оболочки, или как переслать соединение?
Ответ №2:
Смотрите информацию о интерфейсных и внутренних процессах и примеры для команды Db2. По сути, команда db2 имеет пользовательский интерфейс (front-end) и связанный с ним внутренний процесс (подключение к базе данных, контекст и т.д.). Когда вы вызываете скрипт и выполняете напрямую db2
, он может подключаться к внутреннему процессу, который поддерживает подключение к базе данных.
При выполнении команды в круглых скобках, (db2 ...)
создается новый подпроцесс (подоболочка). Это другая среда и в ней нет информации о внутреннем процессе и, следовательно, о подключении к базе данных Db2.
Ответ №3:
Это зависит от командной строки.
bash
открывает вложенную оболочку, у которой нет подключения к вашему фоновому процессу db2 ( db2bp
), который поддерживает подключение к базе данных.
Попробуйте ksh. Он не должен открывать вложенную оболочку. Если вы используете dot space file
обозначение, ksh должен быть установлен для вашего родительского сеанса:
$ ksh
$ db2 connect to mydb ...
$ . ./select.sh