查找已更改的行(带空值的复合键)

时间:2012-01-16 09:20:46

标签: sql sql-server-2008 tsql

我正在尝试构建一个查询,该查询将从源表中获取所有已更改的行,并将其与目标表进行比较。

主键(它实际上并未定义为主键,我们所知道的唯一行)是由许多外键组成的复合键。大约15个,大多数可以有NULL值。为简单起见,我们假设主键包含这三个键列,并且需要比较2个值字段:

CREATE TABLE SourceTable 
(
    Key1 int NOT NULL,
    Key2 nvarchar(10),
    Key3 int,
    Value1 nvarchar(255),
    Value2 int
)

如果Key1 = 1,Key2 = NULL,Key3 = 4.那么我想将它与目标中与关键字段中具有完全相同值的行进行比较。在密钥2中包含NULL。

值字段也可以包含NULL值。

那么在设计像这样的查询时最好的方法是什么,其中NULL值应该被视为实际值并进行比较? 一片空白?合并?相交?

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

ANSI SQL具有尚未在SQL Server中实现的IS [NOT] DISTINCT FROM构造(Connect request)。

但是,使用EXCEPT / INTERSECT的SQL Server中可能simulate this functionality。在比较中,这两者都将NULL视为相等。您希望找到键列相同但值列不同的行。所以这应该做到。

SELECT *
FROM   SourceTable S
       JOIN DestinationTable D
         ON S.Key1 = D.Key1
            /*Join the key columns on equality*/
            AND NOT EXISTS (SELECT S.Key2,
                                   S.Key3
                            EXCEPT
                            SELECT D.Key2,
                                   D.Key3)  
             /*and the value columns on unequality*/
            AND NOT EXISTS (SELECT S.Value1,
                                   S.Value2
                            INTERSECT
                            SELECT D.Value1,
                                   D.Value2)  

答案 1 :(得分:1)

Null与外键不兼容:将null更改为值(在SQL Server中)不会导致它在更新时级联。

最好避免空值(以及其他许多原因!)而是让DBA提名相同数据类型但在域类型之外的其他“魔术”值。示例:日期:远期或远期日期值。 INTEGER:零值或负值。 VARCHAR:双花括号中的值,表示元数据值,例如'{{NONE}}''{{UNKNOWN}}''{{NA}}'等,然后是CHECK约束,以确保值无法以双花括号开始/结束。

或者,在relvar(闭合世界假设)中缺少元组来模拟缺失信息;)