在BULK COLLECT

时间:2018-09-30 00:17:24

标签: oracle plsql plsqldeveloper

我试图将数据从表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 :(得分:2)

首先,由于所读行中的语法错误,上面显示的代码无法执行

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);

好运。

答案 1 :(得分:0)

我检查了而不是仅使用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;