在外壳程序脚本中运行选择时,DB2服务器连接丢失

时间:2019-03-13 09:34:15

标签: sql linux shell 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'从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内容:

  

db2 -x'从SIM.SUPPLIER中选择计数(*)'

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

现在解决方法: 在文件中写入SQL select并调用在select.sh内运行该文件可以确保技巧和连接不会丢失。

select.sh内容

  

回显“从SIM.SUPPLIER中选择计数(*);” > sql

     

db2 -txf sql

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

但这不起作用,我也不明白为什么:

  

回显“从SIM.SUPPLIER中选择计数(*);” > sql

     

回显$(db2 -txf sql)

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

所以有人可以向我解释为什么命令替换会丢失服务器连接,如何继续使用却能保持服务器连接。

PS:我不允许在任何脚本内连接到服务器。出于安全原因,不应将凭据写入文件内部。必须在调用其他脚本之前建立服务器连接,并且只能建立一次。

谢谢

3 个答案:

答案 0 :(得分:1)

原因是VAL=$(....)echo $(db2 -txf sql)都运行一个子外壳,并且在该子外壳中没有数据库连接。您的解决方法不涉及子外壳,因此可以使用。

对于bash,如果无法在脚本中使用connect,则必须像解决方法那样避免Db​​2 CLP的子脱壳。

您可以使用临时文件来避免子shell,但要花更多的时间进行解析。例如,使用VAL=$(db2 ...)而不是db2 ... > $tmpfile,然后再使用VAL=$(cat $tmpfile)或类似技术。

您不能这样“转发连接”。

如果能够将ksh93与协同进程一起使用,则可以在进程之间进行通信,并确保所有db2 CLP操作都在一个任务中发生,然后将结果传递给另一个任务。但是这种复杂性很少值得,并且使用其他非Shell脚本语言可能更可取。

答案 1 :(得分:0)

请参见information about front-end and back-end processes and the examples for the Db2 command。本质上,db2命令具有UI(前端)和相关的后端进程(数据库连接,上下文等)。当您调用脚本并直接执行db2时,它可以连接到拥有数据库连接的后端进程。

在括号(db2 ...)中执行命令时,将产生一个新的子进程(子外壳)。这是一个不同的环境,没有后端进程的信息,因此也没有Db2数据库连接的信息。

答案 2 :(得分:0)

这取决于外壳。
bash打开一个子外壳,该子外壳没有与db2后台进程(db2bp)的连接,该后台进程持有数据库连接。

尝试ksh。它不应该打开一个子外壳。 如果您使用dot space file表示法,则必须为父会话设置ksh:

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