Как я могу дать параметр в PL / SQL курсор - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть таблица из 8k строк, разделенная на подмножество 1k.

Процедура будет вызываться таким образом EXE C BONIFICA_GECT (0); ie, мне нужно запустить команду внутри скрипта только для подмножества = 0 (поле называется лото)

INSERT INTO T_TEST_CI_CO (customerid,customercode) ValueS(v_cid,v_cod);

Я пытаюсь создать процедуру, но я не понимаю, как дать ввод значение на курсоре

CREATE OR REPLACE PROCEDURE BONIFICA_GECT(LOTTO IN NUMBER)
IS

CURSOR id IS
SELECT numero_pratica FROM bonifica1_GECT_2020 WHERE 1=1 lotto=LOTTO
                                               AND (new_status_gect IS NULL OR new_status_gect='PARTIAL_LOAD');

v_pratica bonifica1_GECT_2020.numero_pratica%TYPE;
v_cid     bonifica1_GECT_2020.customerid%TYPE;
v_cod      bonifica1_GECT_2020.customercode%TYPE;
v_lotto NUMBER;
V_CHECK_LOTTO NUMBER;

BEGIN

    OPEN id;
    LOOP
       fetch id INTO v_pratica;
       EXIT WHEN id%NOTFOUND;

       SELECT customerid,customercode INTO v_cid,v_cod
       FROM  bonifica1_GECT_2020
       WHERE numero_pratica=v_pratica;

       INSERT INTO T_TEST_CI_CO (customerid,customercode) ValueS(v_cid,v_cod);

    END LOOP;
    CLOSE id;

COMMIT;

EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
        NULL;
    WHEN OTHERS
    THEN
        /* Consider logging the error and then re-raise */
        RAISE;

END BONIFICA_GECT;

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Ваш курсор в настоящее время имеет (игнорируя паразит 1=1):

CURSOR id IS
SELECT numero_pratica FROM bonifica1_GECT_2020 WHERE lotto=LOTTO
                                               AND (new_status_gect IS NULL OR new_status_gect='PARTIAL_LOAD');

Обе стороны lotto=LOTTO относятся к столбцу в таблице, так что это всегда true (если только значение столбца не имеет значения нулевой); ни одна из сторон не видит аргумента параметра с одинаковым именем.

Вам необходимо присвоить параметру другое имя, например:

CREATE OR REPLACE PROCEDURE BONIFICA_GECT(P_LOTTO IN NUMBER)
IS
  CURSOR id IS
    SELECT numero_pratica
    FROM bonifica1_GECT_2020
    WHERE lotto = P_LOTTO
    AND (new_status_gect IS NULL OR new_status_gect='PARTIAL_LOAD');
...

Вы можете * префикс с Вместо этого имена объектов:

    WHERE bonifica1_GECT_2020.lotto = BONIFICA_GECT.LOTTO

, но я предпочитаю давать аргументы и имена переменных с более простыми префиксами.

Я не уверен, почему вы получаете только идентификатор из курсора, а затем искать другие значения из той же таблицы; Вы можете сделать:

CREATE OR REPLACE PROCEDURE BONIFICA_GECT(P_LOTTO IN NUMBER)
IS
  CURSOR v_cursor IS
    SELECT numero_pratica, customerid, customercode
    FROM bonifica1_GECT_2020
    WHERE lotto = P_LOTTO
    AND (new_status_gect IS NULL OR new_status_gect='PARTIAL_LOAD');

  v_pratica bonifica1_GECT_2020.numero_pratica%TYPE;
  v_cid     bonifica1_GECT_2020.customerid%TYPE;
  v_cod     bonifica1_GECT_2020.customercode%TYPE;
BEGIN

  OPEN v_cursor;
  LOOP
     FETCH v_cursor INTO v_pratica, v_cid, v_cod;
     EXIT WHEN v_cursor%NOTFOUND;

     INSERT INTO T_TEST_CI_CO (customerid,customercode
     VALUES (v_cid, v_cod);

  END LOOP;
  CLOSE v_cursor;
END BONIFICA_GECT;

Вы не можете найти данные без данных (или с вашим оригиналом); и ловить, когда другие не являются хорошей идеей, если вам действительно не нужно регистрировать это где-то.

Вы можете сделать сам параметризованный курсор; снова выбирая другой префикс / имя:

CREATE OR REPLACE PROCEDURE BONIFICA_GECT(P_LOTTO IN NUMBER)
IS
  CURSOR v_cursor (C_LOTTO NUMBER) IS
    SELECT numero_pratica, customerid, customercode
    FROM bonifica1_GECT_2020
    WHERE lotto = C_LOTTO
    AND (new_status_gect IS NULL OR new_status_gect='PARTIAL_LOAD');

  v_pratica bonifica1_GECT_2020.numero_pratica%TYPE;
  v_cid     bonifica1_GECT_2020.customerid%TYPE;
  v_cod     bonifica1_GECT_2020.customercode%TYPE;
BEGIN

  OPEN v_cursor (P_LOTTO);
...

или если вы действительно не хотите иметь префиксы, вы можете указать аргумент из курсора:

CREATE OR REPLACE PROCEDURE BONIFICA_GECT(LOTTO IN NUMBER)
IS
  CURSOR v_cursor (LOTTO NUMBER) IS
    SELECT numero_pratica, customerid, customercode
    FROM bonifica1_GECT_2020
    WHERE lotto = v_cursor.LOTTO
    AND (new_status_gect IS NULL OR new_status_gect='PARTIAL_LOAD');
...
  OPEN v_cursor (LOTTO);
  -- or: OPEN v_cursor (BONIFICA_GECT.LOTTO);
...

В любом случае это действительно полезно, если вы будете повторно использовать курсор с разными аргументами в одной и той же процедуре.

Вы также можете использовать неявный курсор, что проще; но я предполагаю, что это упражнение для такого типа курсора.

Вставка в al oop не очень эффективна, и это можно сделать как один insert .. select; и даже не нужно PL / SQL. Опять же, я предположил, что это часть упражнения.

0 голосов
/ 10 апреля 2020

Если вы ищете параметризованный CURSOR, вы можете попробовать -

CURSOR id(LOTTO NUMBER) IS
SELECT numero_pratica
FROM bonifica1_GECT_2020 
WHERE 1=1
AND lotto=LOTTO
AND (new_status_gect IS NULL OR new_status_gect='PARTIAL_LOAD');
...