stored-procedures - 在db2中使用动态表名

标签 stored-procedures db2 ibm-midrange iseries-navigator

目前,在我的项目开发中,需要根据某些条件生成记录计数,其中表名称存储在单独的表中。例如,xx表将表名称存储在列名称为tableInfo下。

我以这样的方式编写了存储过程

DECLARE FGCURSOR CURSOR FOR SELECT tableInfo FROM xx WHERE col1='PO';

OPEN FGCURSOR;

FETCH FROM FGCURSOR INTO FILEGROUPMEM;

WHILE SQLCODE <> 100
DO

SET COUNTVal =   'SELECT COUNT(*)  FROM  ' ||  FILEGROUPMEM || '  WHERE ICLS=  '  || CLASS  || '  AND  IVEN=  ' || VENDOR  || ' AND ISTY=  ' || STYLE || '  AND ICLR= ' || COLOR || ' AND ISIZ=  ' || SIZE   ; 


IF(COUNTVal  >= 1) THEN 
RETURN 1;
END IF;

FETCH FROM FGCURSOR INTO FILEGROUPMEM;

END WHILE;

CLOSE FGCURSOR;

执行过程时出现异常

Message: [SQL0420] Character in CAST argument not valid. Cause . . . . . : A character in the argument for the CAST function was not correct. Recovery . . . : Change the result data type to one that recognizes the characters in the CAST argument, or change the argument to contain a valid representation of a value for the result data type. Try the request again.

最佳答案

此行不正确:

SET COUNTVal =   'SELECT COUNT(*)  FROM  ' ||  FILEGROUPMEM || '  WHERE ICLS=  '  || CLASS  || '  AND  IVEN=  ' || VENDOR  || ' AND ISTY=  ' || STYLE || '  AND ICLR= ' || COLOR || ' AND ISIZ=  ' || SIZE   ; 

要按照您尝试的方式使用它,您必须使用像这样的静态 SQL 语句

exec sql SELECT COUNT(*) INTO :COUNTVal  
  FROM  MYTBL 
 WHERE ICLS=  :CLASS  AND  IVEN=  :VENDOR  AND ISTY=  :STYLE 
       AND ICLR= :COLOR  AND ISIZ=  :SIZE;

但是,虽然静态语句可以使用变量,但 FROM 子句中的表名不能是变量。

因此您必须准备并使用动态语句。不幸的是,SELECT INTO 不能在动态语句中使用。 VALUES INTO 可以动态使用。

set wSqlStmt = 'VALUES ( SELECT COUNT(*)  FROM  ' ||  FILEGROUPMEM 
                || '  WHERE ICLS=  '  || CLASS  || '  AND  IVEN=  ' 
                || VENDOR  || ' AND ISTY=  ' || STYLE || '  AND ICLR= ' 
                || COLOR || ' AND ISIZ=  ' || SIZE ||') INTO ?';

exec sql PREPARE S1 FROM :wSqlStmt;

exec sql EXECUTE S1 USING COUNTVal;

警告上述代码可能会受到 SQL 注入(inject)攻击。为了防止 SQL 注入(inject),动态 SQL 应使用参数标记,而不是将输入直接连接到语句。虽然您不能对表名称使用参数标记,但您可以对其余变量使用参数标记,如下所示:

set wSqlStmt = 'VALUES ( SELECT COUNT(*)  FROM  ' ||  FILEGROUPMEM 
                || '  WHERE ICLS=  ?  AND  IVEN=  ? ' 
                || '  AND ISTY= ? AND ICLR= ?' 
                || '  AND ISIZ= ?) INTO ?';

exec SQL PREPARE S1 FROM :wSqlStmt;

exec SQL EXECUTE S1 USING :CLASS, :VENDOR, :STYLE, :COLOR, :SIZE, :COUNTVal;

关于stored-procedures - 在db2中使用动态表名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36281235/

相关文章:

ibm-midrange - 您可以使用 RPG 将附加行附加到打印机文件吗?

sql - iSeries - 从 CL 程序调用 SQL 存储过程

sql-server - 链接服务器的存储过程错误

java - 发送 POST 到 HTTPS - 逻辑问题

MySQL存储过程覆盖空参数

带有明细表和事务的 MySQL 存储过程

c - 如何检测ODBC DB2连接编码(代码页)

ibm-midrange - 如何 "Reset"UDF DETERMINISTIC 响应?

node.js - 使用 Electron 构建 Node ibm_db 包时遇到问题

sql - 删除重音 DB2