2

目前在我的项目开发中需要根据某些条件生成记录数,其中表名存储在单独的表中。例如说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 参数中字符的类型,或更改参数以包含结果数据类型值的有效表示。再次尝试请求。

4

1 回答 1

4

此行不正确:

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 注入攻击。为了防止 SQL 注入,动态 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;
于 2016-03-29T13:32:59.093 回答