oracle游标open-for-using给出了错误的结果

时间:2012-07-23 08:06:22

标签: oracle plsql

代码1:

OPEN P_CURSOR FOR V_STR_SQL2
        USING P_USER_ID, P_USER_ID, V_NODEID, V_PROCID, V_ADDRESSE;

输出:0,0,0,0

当我将此代码更改为:

 V_STR_SQL2 := replace(V_STR_SQL2,':P_USER_ID',P_USER_ID);
   V_STR_SQL2 := replace(V_STR_SQL2,':V_NODEID',V_NODEID);
   V_STR_SQL2 := replace(V_STR_SQL2,':V_PROCID',V_PROCID);
   V_STR_SQL2 := replace(V_STR_SQL2,':V_ADDRESSE',V_ADDRESSE);
 OPEN P_CURSOR FOR V_STR_SQL2;

输出:1,0,0,0

第二个输出是正确的。可能是什么原因?任何的想法? 绑定变量的数据类型如下。

  1. userid varchar2,输入
  2. nodeid,procid,number(10)
  3. 地址varchar2(250);
  4.   

    - 已编辑

    当我调试存储过程时,这是执行打开游标之前v_str_sql2的值。当我通过在sqldeveloper中给出它的vlaue来运行这个查询时,它给了我正确的结果。但是公开使用会导致错误的结果。

    SELECT COUNT(DECODE(ZC.STATUS, NULL, 1)) "NEW",
       COUNT(DECODE(ZC.STATUS, 'KEEP', 1)) "KEEP",
       COUNT(DECODE(ZC.STATUS, 'LOCK', 1)) "LOCK",
       COUNT(DECODE(ZC.STATUS,
                    'KEEP',
                    DECODE(UPPER(ZC.STATUS_BY), UPPER(:P_USER_ID), 1))) "PKEEP",
       COUNT(DECODE(ZC.STATUS,
                    'LOCK',
                    DECODE(UPPER(ZC.STATUS_BY), UPPER(:P_USER_ID), 1))) "PLOCK"
      FROM tab1 PARTITION(DCL_OTHERS) DCL,
       tab2      ZC,
       tab3      TC
     WHERE DCL.NODE_ID = TC.NODE_ID
       AND DCL.PROC_ID = TC.PROC_ID
       AND DCL.CASE_REF_NO = TC.CLAIM_REF_NO
       AND DCL.NODE_ID = ZC.NODE_ID(+)
       AND DCL.PROC_ID = ZC.PROC_ID(+)
       AND DCL.CASE_NAME = ZC.CASENUM(+)
       AND DCL.USER_NAME = ZC.USERNAME(+)
       AND DCL.NODE_ID = :V_NODEID
       AND (DCL.PROC_ID = :V_PROCID)
       AND (1 = 1)
       AND DCL.USER_NAME = :V_ADDRESSE
    
      

    编辑2

    我正在使用这种语法。这种语法有问题吗?

        CREATE OR REPLACE PROCEDURE USP_HTH_QUEUEPAGE(P_QUEUENAME VARCHAR2,
                                                  P_CURSOR    OUT SYS_REFCURSOR,
                                                  P_REC_CNT   OUT NUMBER) IS
    BEGIN
      -- CODE TO GENERATE DYNAMIC SQL
      OPEN P_CURSOR FOR V_STR_SQL1
        USING V_ADDRESSE, V_NODEID, V_PROCID, V_STATUS, V_USER_ID, P_EP, P_SP;
      /*END IF;*/
      EXECUTE IMMEDIATE V_STR_SQL2
        INTO P_REC_CNT
        USING V_NODEID, V_PROCID, V_USER_ID, V_STATUS, V_ADDRESSE;
    END;
    

2 个答案:

答案 0 :(得分:0)

请尝试以下

EXECUTE IMMEDIATE V_STR_SQL2
INTO P_REC_CNT
USING  V_USER_ID,V_USER_ID,V_NODEID,V_PROCID, V_ADDRESSE;

以下链接可让您更加了解原因

Dynamic SQL Statement

答案 1 :(得分:0)

我关注的是这一行:

V_STR_SQL2 := replace(V_STR_SQL2,':V_ADDRESSE',V_ADDRESSE);

这会将VARCHAR2变量V_ADDRESSE的内容直接放入查询中,而不会引用任何内容。

考虑到在调试期间获得的V_STR_SQL2的值,V_ADDRESSE的值必须是有效的SQL表达式。如果其值类似于1 High Street,则最终会得到包含

之类的内容的V_STR_SQL2
AND DCL_USER_NAME = 1 High Street

这是无效的SQL。尝试执行此操作时会出错。

那么,V_ADDRESSE可以包含哪些内容?我有两种可能性:

  • 变量V_ADDRESSE的值在两端都包含',例如'1 High Street'
  • 变量V_ADDRESSE的值包含00012493之类的字符串,您希望它与值12493匹配。

V_ADDRESSE究竟包含哪些内容?