1

由于我的 shell 脚本使用超长 SQL 语句多次调用 Db2,我想从脚本中抽象出 SQL 语句并将它们放入一个.sql文件中,然后从 Db2 命令行处理器运行它db2 -f xxx.sql

我希望某些 SQL 语句使用从 shell 脚本传入的变量。

有没有像 Oracle 的方法可以通过'&1'sqlplus在文件中传递变量?.sql

xxx.sql
SELECT * FROM TABLE_A WHERE FIELD_B > &1

CLP
db2 -f xxx.sql 999

这将返回 DB21004E 错误:

DB21004E  You cannot specify both an input file and a command when invoking
the Command Line Processor.
4

3 回答 3

2

会话全局变量可以由在同一 Db2 会话/连接句柄中执行的不同 SQL 语句和脚本进行初始化和引用。这是一个 Db2 SQL 功能,可以在 CLP、clpplus、存储过程、内联/复合 SQL 块以及任何带有 Db2 客户端驱动程序的编程语言中工作。

变量本身是数据库中的永久对象,只需要创建一次。它的名称和数据类型将对数据库中的所有授权用户可见,但存储在变量中的值对于每个连接都是私有的。

首先,创建变量。这只需要执行一次。

db2 "CONNECT TO DBNAME"
db2 "CREATE VARIABLE UTIL.FIELDBMINVALUE INTEGER"

在您的 SQL 脚本中,引用变量而不是文字值。该脚本不能包含任何CONNECT语句,因为这会破坏当前会话。

-- xxx.sql
SELECT * FROM TABLE_A WHERE FIELD_B > UTIL.FIELDBMINVALUE

在运行 SQL 脚本之前,连接到数据库并初始化变量。

db2 "CONNECT TO DBNAME"
db2 "SET UTIL.FIELDBMINVALUE = 999"
db2 -f xxx.sql
db2 "CONNECT RESET"
db2 "TERMINATE"
于 2020-07-23T22:38:13.860 回答
0

Linux/Unix/Windows 上的db2CLP 不支持可替换的参数,这是 IBM 很久以前忽略的。

您可以考虑以下选项之一:

  • 使用基于 java 的clpplus 工具而不是db2CLP 来运行脚本。它模拟了一些 Oracle SQL*plus 功能,包括在命令行上传递位置参数的能力,并在脚本中引用它们等&1&2但是,脚本需要使用 Oracle 样式语法,尽管您的 Db2 服务器不需要 Oracle 兼容性。您还可以获得对查询输出的更多格式控制。

  • 将查询逻辑移动到数据库中的例程中,并在脚本中使用参数调用它们。例如,将查询调用为带有输入参数的存储过程。

  • 使用相关参数动态生成 SQL 脚本并继续使用db2CLP 运行它们。实际上,您正在做自己的变量替换,可能通过类似awksed或类似的工具。

于 2020-07-22T06:54:58.927 回答
0

谢谢楼上大家的回复。

.sql这是我从文件中动态生成 SQL 的方法envsubstoracle .sql这与原始文件非常相似。只需要更改&N$varN.

--xxx.sql
--$var1 : field B remark
--$var2 : field C remark

SELECT * FROM TABLE_A 
    WHERE FIELD_B > $var1
    AND   FIELD_C = $var2 ;
#Script
send_xxx_sql_file () {
var_string=$(for i in $(seq $#); do echo -e "var$i=\${$i} \c"; done)
SQL_statement=$(eval "$var_string envsubst < xxx.sql " | sed '/^--/d' | tr "\n" " " | tr -s " ")
db2 "$SQL_statement"
}

send_xxx_sql_file 999 111

var_string变成var1=${1} var2=${2}

SQL_statement变成SELECT * FROM TABLE_A WHERE FIELD_B > 999 AND FIELD_C = 111 ;

sed '/^--/d'删除带前导的行--

tr "\n" " "用空格替换换行符

tr -s " "将重复空间序列替换为 1 个空间

于 2020-09-11T17:17:34.347 回答