SQL-如果不存在则插入表中-使用现有的NULL值

时间:2019-06-16 06:39:53

标签: sql-server

我需要通过.NET用户应用程序将数据从Excel导入SQL。我需要避免重复。但是,某些记录的某些列中可能有NULL。

我正在使用存储过程来实现导入,但是我似乎无法提供一种“通用”的解决方案来检查匹配数据是否存在,如果不存在则为NULL。

请注意,我的Part表使用了Identity PK,但是导入记录将不包括它。

下面是一个示例(为简洁起见,我没有包括所有列):

CREATE PROCEDURE [dbo].[spInsertPart] 
    (@PartNo NCHAR(50), 
     @PartName NCHAR(50) = NULL,
     @PartVariance NCHAR(30) = NULL)
AS
BEGIN
    SET NOCOUNT OFF;

    IF NOT EXISTS (SELECT PartNo, PartVariance 
                   FROM Part 
                   WHERE PartNo = @PartNo AND PartVariance = @PartVariance)
    BEGIN
        INSERT INTO Part (PartNo, PartName, PartVariance)
        VALUES (@PartNo, @PartName, @PartVariance 
    END
END

导入数据可能包含或可能不包含PartVariance,并且现有记录也可能(也可能不)包含NULL作为PartVariance。

如果两个都为NULL,那么我得到一条重复的记录-我不想要。

如何重新编写不重复的过程,而是将NULL值与其他任何值一样对待? (也就是说,如果其中一个包含NULL,但都不包含NULL,则添加一条记录。)

2 个答案:

答案 0 :(得分:1)

我认为您需要提供以下清楚的信息,才能正确回答此问题: 根据“ Part”表的行对传入记录进行“匹配”的依据是哪些列?这意味着要在哪些列上具有相同的值,则需要用输入值VS来“更新”“ Part”表的其余列,而新记录将“插入”到“ Part”表中。

仅考虑将“ PartNo”和“ PartVariance”列用于查询中的“匹配”,并且只有PartVariance列可以为NULL,这是解决方案:

CREATE PROCEDURE [dbo].[spInsertPart] 
        (@PartNo NCHAR(50), 
         @PartName NCHAR(50) = NULL,
         @PartVariance NCHAR(30) = NULL)
    AS
    BEGIN
        SET NOCOUNT OFF;

        IF NOT EXISTS (
                        SELECT 1 
                        FROM   Part 
                        WHERE  PartNo = @PartNo 
                        AND    COALESCE(PartVariance, '') = COALESCE(@PartVariance, '')
                      )
        BEGIN
            INSERT INTO Part (PartNo, PartName, PartVariance)
            VALUES (@PartNo, @PartName, @PartVariance)
        END
    END

注:-您已经提到只有PartVarince可以为NULL。如果PartNo相同,则COALESCE也可以用于匹配PartNo列。

答案 1 :(得分:0)

嗯,NULL对于SQL Server是个问题。您无法对其进行相等检查(=<>),因为它们都将返回unknown,它们将被翻译为false

但是,您可以结合使用is nullorand以获得所需的结果。

对于sql server 2012或更高版本(在旧版本中,将iif更改为case),您可以执行以下操作:

IF NOT EXISTS (SELECT PartNo, PartVariance 
               FROM Part 
               WHERE IIF((PartNo IS NULL AND @PartNo IS NULL) OR (PartNo = @PartNo), 0, 1) = 1
               AND IIF((PartVariance IS NULL AND @PartVariance IS NULL) OR (PartVariance = @PartVariance), 0, 1) = 1)

如果PartNo@PartNo均为空,或者它们包含相同的值(请记住null =其他任何值都将被评估为false)-IIF将返回0,否则(意味着,列和变量包含不同的值,即使其中之一为null),也将返回1。

当然,第二个iif对其他列/变量组合也做同样的事情。

相关问题