Oracle DB2 CLP在.sql文件中传递变量

Oracle DB2 CLP在.sql文件中传递变量,oracle,shell,db2,clp,Oracle,Shell,Db2,Clp,由于我的shell脚本多次使用超长SQL语句调用Db2,因此我想从脚本中提取SQL语句并将它们放入.SQL文件中,然后从Db2命令行处理器Db2-f xxx.SQL运行它 我希望一些SQL语句使用从shell脚本传入的变量 有没有像Oracle的sqlplus这样的方法可以通过“&1”在.sql文件中传递变量 xxx.sql SELECT * FROM TABLE_A WHERE FIELD_B > &1 CLP db2 -f xxx.sql 999 这将返回一个DB21004

由于我的shell脚本多次使用超长SQL语句调用Db2,因此我想从脚本中提取SQL语句并将它们放入.SQL文件中,然后从Db2命令行处理器Db2-f xxx.SQL运行它

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

有没有像Oracle的sqlplus这样的方法可以通过“&1”在.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.
Linux/Unix/Windows上的DB2CLP不支持可替换参数,IBM很久以前就忽略了这一点

<>你可以考虑以下选项:

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

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

使用相关参数动态生成SQL脚本,并继续使用DB2CLP运行它们。实际上,您正在进行自己的变量替换,可以通过awk和sed等工具进行

可以通过在同一Db2会话/连接句柄中执行的不同SQL语句和脚本初始化和引用。这是一个DB2SQL特性,可以在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"

谢谢你以上的回复

下面是我通过envsubt从.SQL文件动态生成SQL的方法。这与原始的oracle.sql文件非常相似。只需将&N更改为$varN即可

var_字符串变为var1=${1}var2=${2}

SQL_语句从表_A变为SELECT*,其中字段_B>999,字段_C=111

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

tr\n用空格替换换行符

tr-s将重复的空格序列替换为1个空格

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