导入大量数据后,我试图自动执行一些约束检查,但遇到了流动问题。我找到了一种解决方法,我还将对此进行描述,但是如果有人比我具有更好的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:我不允许在任何脚本内连接到服务器。出于安全原因,不应将凭据写入文件内部。必须在调用其他脚本之前建立服务器连接,并且只能建立一次。
谢谢
答案 0 :(得分:1)
原因是VAL=$(....)
和echo $(db2 -txf sql)
都运行一个子外壳,并且在该子外壳中没有数据库连接。您的解决方法不涉及子外壳,因此可以使用。
对于bash,如果无法在脚本中使用connect
,则必须像解决方法那样避免Db2 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