не может смешиваться между одной строкой и несколькими строками (BULK) в списке INTO. ОШИБКА в proc - PullRequest
0 голосов
/ 13 мая 2019
CREATE OR REPLACE PROCEDURE RDBSTAGE.ATCHMNT_ERR_FILEID AUTHID CURRENT_USER
IS
  CURSOR cv_atchtab IS
    SELECT * FROM ATTACHMENT_ERROR;
  I_ATCHMNT_ERR cv_atchtab%ROWTYPE;
  V_FILE_ID VARCHAR2(40);
BEGIN
  OPEN cv_atchtab;
  LOOP
    FETCH cv_atchtab BULK COLLECT INTO I_ATCHMNT_ERR;
    EXIT WHEN cv_atchtab%NOTFOUND;
    FOR i IN 1..I_ATCHMNT_ERR.COUNT
    LOOP
      SELECT FILE_ID BULK COLLECT
      INTO V_FILE_ID
      FROM ATTACHMENT_CLAIM t1
      WHERE t1.CLAIM_TCN_ID=I_ATCHMNT_ERR(i).CLAIM_TCN_ID;
      UPDATE ATTACHMENT_ERROR
      SET FILE_ID          = V_FILE_ID
      WHERE t1.CLAIM_TCN_ID=I_ATCHMNT_ERR.CLAIM_TCN_ID;
    END LOOP;

  END LOOP;    
  CLOSE cv_atchtab;    
END;

END ATCHMNT_ERR_FILEID;

/
SHOW ERRORS 

Процедура ATCHMNT_ERR_FILEID скомпилирована

Ошибки: проверить журнал компиляции Ошибки для PROCEDURE RDBSTAGE.ATCHMNT_ERR_FILEID:
LINE / COL ERROR


11/40 PLS-00497: нельзя смешивать одну строку и несколько строк (BULK) в списке INTO
14/5 PL / SQL: оператор игнорируется
14/31 PLS-00302: компонент 'COUNT' должен быть объявлен

1 Ответ

0 голосов
/ 13 мая 2019

PLS-00497: невозможно смешивать однострочные и многострочные (BULK) в списке INTO

BULK COLLECT INTO - это синтаксис для заполнения коллекции PL / SQL из запроса,Но ваш код заполняет скалярную однорядную переменную.

14/31 PLS-00302: компонент 'COUNT' должен быть объявлен

I_ATCHMNT_ERR.COUNT недопустим, поскольку count() применяется только к коллекциям. I_ATCHMNT_ERR является скалярным.

Чтобы исправить это, вам нужно определить и использовать типы коллекций.Примерно так:

CREATE OR REPLACE PROCEDURE ATCHMNT_ERR_FILEID
IS
  CURSOR cv_atchtab IS
    SELECT * FROM ATTACHMENT_ERROR;

  type ATCHMNT_ERR_nt is table of cv_atchtab%ROWTYPE;
  I_ATCHMNT_ERR ATCHMNT_ERR_nt;

  V_FILE_ID VARCHAR2(40);
BEGIN
  OPEN cv_atchtab;
  LOOP
    FETCH cv_atchtab BULK COLLECT INTO I_ATCHMNT_ERR; -- collection type
    EXIT WHEN I_ATCHMNT_ERR.COUNT = 0; -- changed this

    FOR i IN 1..I_ATCHMNT_ERR.COUNT
    LOOP
      SELECT FILE_ID 
      INTO V_FILE_ID  -- scalar type
      FROM ATTACHMENT_CLAIM t1
      WHERE t1.CLAIM_TCN_ID = I_ATCHMNT_ERR(i).CLAIM_TCN_ID;

      UPDATE ATTACHMENT_ERROR t2 -- changed this
      SET FILE_ID = V_FILE_ID
      WHERE t2.CLAIM_TCN_ID = I_ATCHMNT_ERR(i).CLAIM_TCN_ID;  -- changed this
    END LOOP;

  END LOOP;    
  CLOSE cv_atchtab; 

END ATCHMNT_ERR_FILEID; 

Вот демонстрация fiddle db <> из вышеприведенного , работающая против моего предположения о модели данных.

Документация Oracle является полной, онлайн и бесплатной.В PL / SQL Guide есть целая глава о коллекциях и записях, которую я предлагаю вам прочитать. Найдите здесь .


Кроме того, вложенные циклы с такими однострочными операторами обычно являются красным флагом в PL / SQL.Они довольно неэффективны и медленны.SQL является языком, основанным на множествах, и мы всегда должны пытаться решать проблемы, используя SQL, когда это возможно, и в идеале в одном выражении, основанном на множествах.Если этот код предназначен для производства (а не является домашним заданием), вам определенно следует переписать его более продуктивно.

...