2

現在、私のプロジェクト開発では、テーブル名が別のテーブルに格納されている特定の基準に基づいてレコード数を生成する必要があります。たとえば、xx テーブルが列名の下にテーブル名を格納しているとします。

私はそのような方法でストアドプロシージャを書きました

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 に答える