首页 > 解决方案 > 处理 BULK COLLECT 中的空值

问题描述

我试图将数据从表 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;

标签: oracleplsqlplsqldeveloper

解决方案


首先,上面显示的代码不会执行,因为读取的行中有语法错误

PEU_SEGUNDO_NOMBRE,

cur_rows (I).PEU_SEGUNDO_NOMBRE,

结尾的逗号将导致编译失败。

其次,逐行处理往往很慢,即使您从数据库将数据批量收集到内存中也是如此。我建议您使用 a 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);

祝你好运。


推荐阅读