Обрабатывать нулевые значения в BULK COLLECT - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь передать данные из таблицы A в таблицу B, но сначала мне нужно проверить, не находятся ли данные, которые я пытаюсь вставить, в таблице B. Я делаю это с помощью запроса, если он существует, и возвращает идентификацию.Проблема заключается в том, что второе выполнение выдает уникальное нарушение ограничения, поэтому появляется проверка для сравнения, если существующая в таблице B не работает, или условие в операторе if неверно.

  DECLARE

       LN_EXIST       NUMBER;

       CURSOR cur
       IS
            SELECT *
              FROM table_A


       TYPE cur_aat IS TABLE OF cur%ROWTYPE
          INDEX BY PLS_INTEGER;

       cur_rows                cur_aat;
    BEGIN
       OPEN cur;

       LOOP
          FETCH cur BULK COLLECT INTO cur_rows LIMIT 1000;

          EXIT WHEN cur%NOTFOUND;                      /* cause of missing rows */

          FOR I IN 1 .. cur_rows.COUNT
          LOOP
             LN_EXIST := 0;

             BEGIN
                DBMS_OUTPUT.put_line (cur_rows (I).PEU_IDENTIFICACION);

                SELECT PUV.PEU_IDENTIFICACION -- check
                         INTO LN_EXIST
                  FROM table_b PUV
                 WHERE (CASE
                           WHEN     PUV.PEU_IDENTIFICACION =
                                       cur_rows (I).PEU_IDENTIFICACION
                                AND NVL (PUV.PEU_PRIMER_NOMBRE, '0') =
                                       NVL (cur_rows (I).PEU_PRIMER_NOMBRE, '0')
                                AND NVL (PUV.PEU_SEGUNDO_NOMBRE, '0') =
                                       NVL (cur_rows (I).PEU_SEGUNDO_NOMBRE, '0')
                                AND PUV.PEU_PRIMER_APELLIDO =
                                       cur_rows (I).PEU_PRIMER_APELLIDO
                                AND NVL (PUV.PEU_SEGUNDO_APELLIDO, '0') =
                                       NVL (cur_rows (I).PEU_SEGUNDO_APELLIDO,
                                            '0')
                                AND PUV.PEU_FECHA_NACIMIENTO =
                                       cur_rows (I).PEU_FECHA_NACIMIENTO
                           THEN
                              'S'
                           ELSE
                              'N'
                        END) = 'S';
             EXCEPTION
                WHEN OTHERS
                THEN
                   LN_EXIST:= 0;
             END;

             IF LN_EXIST!= 0     --if not exist
             THEN
                INSERT
                  INTO table_b (PEU_ID,
                                               PEU_IDENTIFICACION,
                                               PEU_PRIMER_APELLIDO,
                                               PEU_SEGUNDO_APELLIDO,
                                               PEU_PRIMER_NOMBRE,
                                               PEU_SEGUNDO_NOMBRE,
                                               )
                VALUES (cur_rows (I).PEU_ID,     
                        cur_rows (I).PEU_TIPO_IDENTIFICACION,
                        cur_rows (I).PEU_IDENTIFICACION,
                        cur_rows (I).PEU_PRIMER_APELLIDO,
                        cur_rows (I).PEU_SEGUNDO_APELLIDO,
                        cur_rows (I).PEU_PRIMER_NOMBRE,
                        cur_rows (I).PEU_SEGUNDO_NOMBRE,
                        );
             END IF;
          END LOOP;

          EXIT WHEN cur%NOTFOUND;
       END LOOP;

       COMMIT;

       CLOSE cur;
    END;

Ответы [ 2 ]

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

Я проверил, вместо того, чтобы использовать только оператор select, я добавил оператор count, чтобы определить общее количество совпадений, которые существуют с параметрами, которые я установил, поэтому все время будет возвращать значение, если не существует 0 иесли существует другое значение, отличное от 0.

DECLARE

       LN_EXIST       NUMBER;

       CURSOR cur
       IS
            SELECT *
              FROM table_A


       TYPE cur_aat IS TABLE OF cur%ROWTYPE
          INDEX BY PLS_INTEGER;

       cur_rows                cur_aat;
    BEGIN
       OPEN cur;

       LOOP
          FETCH cur BULK COLLECT INTO cur_rows LIMIT 1000;

          EXIT WHEN cur%NOTFOUND;                      /* cause of missing rows */

          FOR I IN 1 .. cur_rows.COUNT
          LOOP

                DBMS_OUTPUT.put_line (cur_rows (I).PEU_IDENTIFICACION);

                SELECT COUNT (PUV.PEU_IDENTIFICACION) -- check
                         INTO LN_EXIST
                  FROM table_b PUV
                 WHERE (CASE
                           WHEN     PUV.PEU_IDENTIFICACION =
                                       cur_rows (I).PEU_IDENTIFICACION
                                AND NVL (PUV.PEU_PRIMER_NOMBRE, '0') =
                                       NVL (cur_rows (I).PEU_PRIMER_NOMBRE, '0')
                                AND NVL (PUV.PEU_SEGUNDO_NOMBRE, '0') =
                                       NVL (cur_rows (I).PEU_SEGUNDO_NOMBRE, '0')
                                AND PUV.PEU_PRIMER_APELLIDO =
                                       cur_rows (I).PEU_PRIMER_APELLIDO
                                AND NVL (PUV.PEU_SEGUNDO_APELLIDO, '0') =
                                       NVL (cur_rows (I).PEU_SEGUNDO_APELLIDO,
                                            '0')
                                AND PUV.PEU_FECHA_NACIMIENTO =
                                       cur_rows (I).PEU_FECHA_NACIMIENTO
                           THEN
                              'S'
                           ELSE
                              'N'
                        END) = 'S';

             IF LN_EXIST!= 0     --if not exist
             THEN
                INSERT
                  INTO table_b (PEU_ID,
                                               PEU_IDENTIFICACION,
                                               PEU_PRIMER_APELLIDO,
                                               PEU_SEGUNDO_APELLIDO,
                                               PEU_PRIMER_NOMBRE,
                                               PEU_SEGUNDO_NOMBRE,
                                               )
                VALUES (cur_rows (I).PEU_ID,     
                        cur_rows (I).PEU_TIPO_IDENTIFICACION,
                        cur_rows (I).PEU_IDENTIFICACION,
                        cur_rows (I).PEU_PRIMER_APELLIDO,
                        cur_rows (I).PEU_SEGUNDO_APELLIDO,
                        cur_rows (I).PEU_PRIMER_NOMBRE,
                        cur_rows (I).PEU_SEGUNDO_NOMBRE,
                        );
             END IF;
          END LOOP;

          EXIT WHEN cur%NOTFOUND;
       END LOOP;

       COMMIT;

       CLOSE cur;
    END;
0 голосов
/ 30 сентября 2018

Прежде всего, приведенный выше код не будет выполняться из-за синтаксических ошибок в строках, которые читают

PEU_SEGUNDO_NOMBRE,

и

cur_rows (I).PEU_SEGUNDO_NOMBRE,

Завершающие запятые будут вызывать компиляциюсбой.

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

MERGE INTO TABLE_B b
  USING TABLE_A a
    ON (b.PEU_IDENTIFICACION = a.PEU_IDENTIFICACION AND
        NVL(b.PEU_PRIMER_NOMBRE, '0') = NVL (a.PEU_PRIMER_NOMBRE, '0') AND
        NVL (b.PEU_SEGUNDO_NOMBRE, '0') = NVL(a.PEU_SEGUNDO_NOMBRE, '0') AND
        b.PEU_PRIMER_APELLIDO = a.PEU_PRIMER_APELLIDO AND
        NVL(b.PEU_SEGUNDO_APELLIDO, '0') = NVL(a.PEU_SEGUNDO_APELLIDO, '0') AND
        b.PEU_FECHA_NACIMIENTO = a.PEU_FECHA_NACIMIENTO)
  WHEN NOT MATCHED THEN
    INSERT (PEU_ID,
            PEU_IDENTIFICACION,
            PEU_PRIMER_APELLIDO,
            PEU_SEGUNDO_APELLIDO,
            PEU_PRIMER_NOMBRE,
            PEU_SEGUNDO_NOMBRE)
    VALUES (a.PEU_ID,     
            a.PEU_TIPO_IDENTIFICACION,
            a.PEU_IDENTIFICACION,
            a.PEU_PRIMER_APELLIDO,
            a.PEU_SEGUNDO_APELLIDO,
            a.PEU_PRIMER_NOMBRE,
            a.PEU_SEGUNDO_NOMBRE);

Удачи.

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