Если ваш реальный код объявлен как RC_TABLE0
как курсор ref, тогда ваша переменная обнуляется, потому что открытие курсора в что-то действительно ничего не делает.Вы не можете открыть курсор и выбрать что-то из запроса курсора одновременно в отдельную переменную, в зависимости от того, как вы пытаетесь это сделать.Вам нужен или курсор, или простой 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: неверный курсор», если вы закроете его внутри процедуры).
Вы не можете сделать и то и другое, если только вы снова не откроете курсор, который выглядит как накладные расходы, которые вы, вероятно, не хотите ...