Oracle один ряд в переменную - PullRequest
0 голосов
/ 19 октября 2018

Мне нужно получить все результаты в одной строке ... это работает, но когда я хочу увидеть его в 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 в порядке.

1 Ответ

0 голосов
/ 19 октября 2018

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

Вы не можете сделать и то и другое, если только вы снова не откроете курсор, который выглядит как накладные расходы, которые вы, вероятно, не хотите ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...