问题描述
我有一个自动过程,可以根据定义的表主键进行增量插入。有几张表,主键有空值,我们在根上也做不了什么来解决,只好自己处理。
DELETE FROM table
USING stg_table
WHERE table.pk_1 = stg_table.pk_1 AND table.pk_2 = stg_table.pk_2
除非 pk_1
或 pk_2
中的某些值为空,否则此方法有效。我已经做了以下工作来解决它:
DELETE FROM table
USING stg_table
WHERE NVL(table.pk_1,'null') = NVL(stg_table.pk_1,'null')
但是,这仅在 pk_1
为 VARCHAR
时才有效,否则会失败。
我可以修改我的自动化脚本并获取每列的类型,并根据它向 NVL 函数传递不同的值,但我想知道是否有任何方法可以仅使用 SNowflake 正确实现删除。
解决方法
如果您希望 NULL
值匹配,您可以使用:
DELETE FROM table
USING stg_table
WHERE (table.pk_1 = stg_table.pk_1 OR table.pk_1 IS NULL AND stg_table.pk_1 IS NULL) AND
(table.pk_2 = stg_table.pk_2 OR table.pk_2 IS NULL AND stg_table.pk_2 IS NULL)
或者,使用 EQUAL_NULL()
,Snowflake 的 NULL 安全比较运算符:
DELETE FROM table
USING stg_table
WHERE EQUAL_NULL(table.pk_1,stg_table.pk_1) AND
EQUAL_NULL(table.pk_2,stg_table.pk_2);
综上所述,主键从不 NULL
-- 根据 SQL 的定义。并且创建数据库中两个不同表中的 NULL
值应该匹配的情况非常罕见。
IS DISTINCT FROM
是空安全运算符,它允许比较元组:
DELETE FROM table
USING stg_table
WHERE (table.pk_1,table.pk_2) IS NOT DISTINCT FROM (stg_table.pk_1,stg_table.pk_2);