在db2中使用动态表名

时间:2016-03-29 10:06:27

标签: 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;

在执行说明

的程序时获取异常
  

消息:[SQL0420] CAST参数中的字符无效。原因。 。 。 。   。 :CAST函数的参数中的字符不是   正确。恢复。 。 。 :将结果数据类型更改为一个   识别CAST参数中的字符,或更改参数   包含结果数据类型的值的有效表示。   再次尝试请求。

1 个答案:

答案 0 :(得分:3)

这一行不正确:

Array.from({length: 10},(v,i) => (i + 1) * 6)

要以您尝试的方式使用它,您必须使用类似的静态SQL语句

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

但是,虽然静态语句可以使用变量,但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

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

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;