oracle - 处理 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;
解决方案
首先,上面显示的代码不会执行,因为读取的行中有语法错误
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);
祝你好运。
推荐阅读
- r - 如何在具有多个列对的数据框中按名称连接两对列并移动行
- python - 如何通过已知坐标找到四边形的角
- javascript - 如何接收博客文章数据
- c - 从 Unix 域套接字读取整数个 SOCK_SEQPACKET 消息
- vue.js - nuxt 链接需要两次点击才能更正路径
- android - 自由形式多窗口模式活动定位不起作用
- c - 在 openssl CLI 和 C codeHello 之间获取不同的加密字符串
- python - ValueError:x 和 y 必须具有相同的第一维,但具有形状 (100,) 和 (396,)
- typescript - 如何使用 Yarn 2.0 的链接启用 VS Code 自动导入:协议和 Typescript
- python - Python Pandas Dataframe 丰富(来自另一个)