【问题标题】:Handling multi-valued parameter in DB2 Stored Procedure在 DB2 存储过程中处理多值参数
【发布时间】:2019-12-19 07:41:05
【问题描述】:

我有一个带有输入参数的存储过程,它是 Varchar 的一个多值参数。 传递的参数被传递给查询的 IN 子句。 我无法弄清楚如何在存储过程中处理它。 到现在为止,我有这个(这是实际存储过程的sn-p):

CREATE OR replace PROCEDURE <SCHEMA>.Some_Proc
(
 IN V_INDSTRY_DESCRPTN VARCHAR (2000)


)
DYNAMIC RESULT SETS 1
BEGIN
DECLARE WHERE_CLAUSE VARCHAR(5000) DEFAULT '';
DECLARE OUTER_CLAUSE VARCHAR(2000) DEFAULT '';
DECLARE V_SQL VARCHAR(10000) DEFAULT '';
DECLARE CSR_RSLT_SET CURSOR WITH RETURN FOR S1;
IF (V_INDSTRY_DESCRPTN != 'ALL') THEN 
SET WHERE_CLAUSE = WHERE_CLAUSE || 'AND industry.INDSTRY_DESCRPTN in ( '''||V_INDSTRY_DESCRPTN||''')'  ;
END IF; 
SET V_SQL ='<SOME QUERY>'
/*some other logic goes here*/
PREPARE S1 FROM V_SQL;
OPEN CSR_RSLT_SET;
END

我这样调用程序:

CALL <SCHEMA>.Some_Proc ('industry1')

1)如何在同一个参数中发送多个值? CALL &lt;SCHEMA&gt;.Some_Proc ("'industry1','industry2'") 给出编译错误 2)如何处理过程中的多值参数。

【问题讨论】:

    标签: stored-procedures db2


    【解决方案1】:

    按原样尝试:

    --#SET TERMINATOR @
    
    CREATE OR REPLACE PROCEDURE TEST_MULTIVALUE(P_TABSCHEMAS VARCHAR(128))
    DYNAMIC RESULT SETS 1
    BEGIN
      DECLARE L_STMT VARCHAR(200);
      DECLARE C1 CURSOR WITH RETURN FOR S1;
    
      SET L_STMT = 'SELECT TABSCHEMA, TABNAME FROM SYSCAT.TABLES WHERE TABSCHEMA IN ('||P_TABSCHEMAS||')';
      CALL DBMS_OUTPUT.PUT_LINE(L_STMT);
      PREPARE S1 FROM L_STMT;
      OPEN C1;
    END@
    
    SET SERVEROUTPUT ON@
    
    CALL TEST_MULTIVALUE('''SYSCAT''')@
    CALL TEST_MULTIVALUE('''SYSCAT'', ''SYSSTAT''')@
    

    对于那些害怕sql注入的人

    我们用逗号分隔的字符串对输入参数进行标记,生成一个字符串表。

    CREATE OR REPLACE PROCEDURE TEST_MULTIVALUE_STATIC(P_TABSCHEMAS VARCHAR(128))
    DYNAMIC RESULT SETS 1
    BEGIN
      DECLARE C1 CURSOR WITH RETURN FOR
        SELECT TABSCHEMA, TABNAME
        FROM SYSCAT.TABLES T
        WHERE EXISTS
        (
          SELECT 1
          FROM XMLTABLE 
          (
          'for $id in tokenize($s, "\s*,\s*") return <i>{string($id)}</i>' 
          passing P_TABSCHEMAS as "s"
          COLUMNS
            TOK VARCHAR(128) PATH '.'
          ) P
          WHERE P.TOK=T.TABSCHEMA
        );
      OPEN C1;
    END
    @
    
    CALL TEST_MULTIVALUE_STATIC('SYSCAT')@
    CALL TEST_MULTIVALUE_STATIC('SYSCAT, SYSSTAT')@
    

    【讨论】:

    • !您在语句中使用直接字符串连接,这意味着这很容易受到 SQL 注入的攻击。这尤其令人震惊,因为有一个 PREPARE 声明在下一行。
    【解决方案2】:

    我猜你的问题实际上是,如何在符合标准的 SQL 中转义字符文字(由单引号括起来)中的单引号。答案是,将它们加倍:

    CALL <SCHEMA>.Some_Proc ('''industry1'',''industry2''')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      • 2018-10-31
      • 1970-01-01
      相关资源
      最近更新 更多