oracle - oracle单行变成变量
问题描述
我需要在一行中获得所有结果......它正在工作,但是当我想在 dbms 中看到它时,没有任何想法......为什么?
CREATE OR REPLACE PROCEDURE NXMESEP.SP_IN_CHECK_AND_SEND_SMS
( RC_TABLE0 OUT SYS_REFCURSOR,
RS_CODE OUT VARCHAR2, -- RETURN 코드
RS_MSG OUT VARCHAR2
) IS ERROR_EXCEPTION EXCEPTION;
BEGIN
begin
DECLARE
promena varchar2(32767);
BEGIN
OPEN RC_TABLE0 FOR
SELECT listagg(ITEM_ID,', ') within group(order by ITEM_ID)
INTO promena
FROM TB_PL_M_WRKORD WRKOD
WHERE 1 = 1
AND WO_DATE = '20181012'
AND WRKOD.ITEM_ID NOT IN (SELECT ITEM_ID FROM TB_CM_M_FERT_COST_CHK FERT)
AND WC_ID = 'U';
LOOP
FETCH rc_table0 INTO promena;
EXIT WHEN rc_table0%NOTFOUND;
dbms_output.put_line(promena);
END LOOP;
CLOSE rc_table0;
end;
EXCEPTION
.... END;
RS_CODE := 'S'; RS_MSG := 'Complete successfully!';
RETURN; END SP_CHECK_AND_SEND_SMS; /
这应该是我所期望的。
" 12993NXUA, 13595NXUA, 14495NXUA, 16589NX, 16589NX, 16590NX, 16590NX, 16622NX, 16622NX "
现在它正在工作,但每次执行时我都会收到未知错误 ORA-65535。但在此之后我可以看到 dbms 结果是好的。
解决方案
假设您的真实代码已RC_TABLE0
声明为 ref 游标,那么您的变量最终为 null,因为将游标打开到某些东西并没有真正做任何事情。您不能同时打开游标并将游标查询中的某些内容选择到单独的变量中,无论您尝试采用哪种方式。您需要一个游标或一个简单的select ... into
:
DECLARE
promena varchar2(32767);
BEGIN
SELECT listagg(ITEM_ID,', ') within group (order by ITEM_ID)
INTO promena
FROM TB_PL_M_WRKORD WRKOD
WHERE 1 = 1
AND WO_DATE = '20181012'
AND WRKOD.ITEM_ID NOT IN (SELECT ITEM_ID FROM TB_CM_M_FERT_COST_CHK FERT)
AND WC_ID = 'U';
dbms_output.put_line('test: '||promena);
END;
/
test: 12993NXUA, 13595NXUA, 14495NXUA ...
PL/SQL procedure successfully completed.
当然,您还必须set serveroutput on
或等效地实际看到结果。
我还删除了多余distinct
的、不必要的select .. from dual
——这似乎是奇怪游标结构的一部分——以及begin/end
.
顺便说一句,您的代码暗示这wo_date
是一个字符串,这似乎不太可能,或者至少不理想。如果它实际上是一个真实的日期,那么您不应该使用字符串进行比较,因为您正在强制进行隐式转换;改用实际日期,可能是 ANSI 日期文字:
AND WO_DATE = DATE '2018-10-12'
如果您确实想使用显式游标方法,则需要使用循环来填充字符串变量:
DECLARE
promena varchar2(32767);
rc_table0 sys_refcursor;
BEGIN
OPEN rc_table0 FOR
SELECT DISTINCT listagg(ITEM_ID,', ') within group (order by ITEM_ID)
FROM TB_PL_M_WRKORD WRKOD
WHERE 1 = 1
AND WO_DATE = '20181012'
AND WRKOD.ITEM_ID NOT IN (SELECT ITEM_ID FROM TB_CM_M_FERT_COST_CHK FERT)
AND WC_ID = 'U';
LOOP
FETCH rc_table0 INTO promena;
EXIT WHEN rc_table0%NOTFOUND;
dbms_output.put_line('test: '||promena);
END LOOP;
CLOSE rc_table0;
END;
/
由于您只期望返回一行,因此这样做没有多大意义;如果您期望多行(来自修改后的查询,例如获取几天的数据并按天分组),那么隐式游标无论如何都会更简单:
BEGIN
FOR r IN (
SELECT DISTINCT listagg(ITEM_ID,', ') within group (order by ITEM_ID) AS promena
FROM TB_PL_M_WRKORD WRKOD
WHERE 1 = 1
AND WO_DATE = '20181012'
AND WRKOD.ITEM_ID NOT IN (SELECT ITEM_ID FROM TB_CM_M_FERT_COST_CHK FERT)
AND WC_ID = 'U'
)
LOOP
dbms_output.put_line('test: '||r.promena);
END LOOP;
END;
/
如果这确实是过程的一部分并且rc_table0
是OUT
参数,那么您就不能这样做。在您发布为您尝试的答案的代码中:
OPEN RC_TABLE0 FOR
SELECT listagg(ITEM_ID,', ') within group(order by ITEM_ID)
INTO promena
FROM TB_PL_M_WRKORD WRKOD
...
在该构造中,into
仍然忽略了,因为open
没有获取任何东西。如果你像我上面那样在你的过程中循环和获取以显示结果,那么你正在使用结果集,所以调用者将不会得到任何结果(或者“ORA-01001:无效游标”,如果你在过程中关闭它) .
你不能同时做这两个,除非你重新打开光标,这似乎是你可能不想要的开销......
推荐阅读
- azure-devops - Azure DevOps - 跨组织共享测试步骤
- c# - 如何从asp webform gridview获取数据ID
- html - 当字段集的子项时,具有溢出自动的滚动 Div 不包含表
- c# - WPF 图表中的自定义工具提示
- laravel-5 - 在 laravel 中使用 typeahead 进行 JQuery 自动完成搜索
- vue.js - 将 var 传递给 meta 中的 vue 路由器
- django - django celery AsyncResult AttributeError: 'DisabledBackend' 对象没有属性 '_get_task_meta_for'
- java - 无法在 Eclipse 中导出到存档文件“访问被拒绝”
- ansible - 稳定 | 错误!任务中未检测到任何操作。这通常表示模块名称拼写错误或模块路径不正确
- cytoscape.js - 方向感知邻里