oracle cursor open-for-using给出错误的结果
Posted
技术标签:
【中文标题】oracle cursor open-for-using给出错误的结果【英文标题】:oracle cursor open-for-using giving wrong result 【发布时间】:2012-07-23 08:06:21 【问题描述】:代码 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
第二个输出是正确的。可能是什么原因?任何的想法? 绑定变量的数据类型如下。
-
userid varchar2,输入
nodeid,procid, number(10)
地址 varchar2(250);
-- 已编辑
当我调试我的存储过程时,这是在执行打开游标之前 v_str_sql2 的值。当我通过在 sqldeveloper 中给出它的值来运行这个查询时,它给了我正确的结果。但是开放使用的结果错误。
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;
【问题讨论】:
不知道你的查询是什么,两个代码 sn-ps 之间的关系,关于你的数据的任何信息,任何关于输出代表什么的想法等等。很难推测。如果您发布 SQL 语句,我们至少会有一些工作要做。如果您发布一个我们可以在我们的机器上运行的简单测试用例,您几乎肯定会得到答案。 感谢贾斯汀的回复。我已经编辑了我的帖子。 嗨 Justin Cave.. 有什么意见吗?如果您需要任何其他信息,请告诉我。 我通常不会期望查询在replace(V_STR_SQL2,':P_USER_ID',P_USER_ID)
之后起作用;如果P_USER_ID
是字符串,则查询现在将该字符串的值 视为列名,通常导致ORA_00904。这似乎没有发生,所以想知道它是否是一个带有空格的数字。不幸的是,这似乎与问题无关......除非V_NODEID
或V_PROCID
是varchars。你说的不是这样的。
正确。正如你所说,我不喜欢写 replace(V_STR_SQL2,':P_USER_ID',P_USER_ID);但我的代码不适用于 USING。因此,我只剩下这个选项。 :(
【参考方案1】:
请尝试以下
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
【讨论】:
【参考方案2】:我关心的是这里的这一行:
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
究竟包含什么?
【讨论】:
以上是关于oracle cursor open-for-using给出错误的结果的主要内容,如果未能解决你的问题,请参考以下文章
oracle数据库 参数open_cursors和session_cached_cursor详解!
Oracle 中的 oracle cursor(select ..) 查询的目的是啥?