我需要通过.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,则添加一条记录。)
答案 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 null
,or
和and
以获得所需的结果。
对于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
对其他列/变量组合也做同样的事情。