6

下面是一个存储过程,用于根据单独检查所有字段来检查数据库中是否存在重复条目(不要问我为什么要这样做,它只是必须这样)。

这听起来非常简单,但 SP 失败了。问题是传递给 SP 的某些参数可能具有 null 值,因此 sql 应该读取“is null”而不是“= null”。我用 exec() 和 sp_executesql 尝试了 isnull()、case 语句、coalesce() 和动态 sql,但未能实现其中任何一个。这是代码...

CREATE PROCEDURE sp_myDuplicateCheck
 @userId int,
 @noteType char(1),
 @aCode char(3),
 @bCode char(3), 
 @cCode char(3),
 @outDuplicateFound int OUT
AS
BEGIN
SET @outDuplicateFound = (SELECT Top 1 id FROM codeTable 
                          WHERE userId = @userId
                          AND noteType = @noteType
                          AND aCode = @aCode
                          AND bCode = @bCode
                          AND cCode = @cCode 
                          )
-- Now set the duplicate output flag to a 1 or a 0
IF (@outDuplicateFound IS NULL) OR (@outDuplicateFound = '') OR (@outDuplicateFound = 0)
 SET @outDuplicateFound = 0
ELSE 
 SET @outDuplicateFound = 1
END
4

6 回答 6

10

我认为每个可能为空的参数都需要这样的东西:

AND (aCode = @aCode OR (aCode IS NULL AND @aCode IS NULL))
于 2008-12-19T12:59:50.200 回答
7

如果我正确理解了您的问题,那么我鼓励您对以下内容进行一些研究:

SET ANSI_NULLS OFF

如果在存储过程中使用此命令,则可以在比较中使用 = NULL。查看以下示例代码以了解其工作原理。

Declare @Temp Table(Data Int)

Insert Into @Temp Values(1)
Insert Into @Temp Values(NULL)

-- No rows from the following query
select * From @Temp Where Data = NULL

SET ANSI_NULLS OFF

-- This returns the rows where data is null
select * From @Temp Where Data = NULL

SET ANSI_NULLS ON

每当您设置 ANSI_NULLS Off 时,最好尽快将其设置回 ON,因为这可能会影响您稍后运行的其他查询。所有 SET 命令仅影响当前会话,但根据您的应用程序,这可能跨越多个查询,这就是为什么我建议您在此查询后立即重新打开 ansi nulls。

于 2008-12-19T13:38:02.590 回答
1

我认为这应该与 COALESCE 功能一起使用。试试这个:

CREATE PROCEDURE sp_myDuplicateCheck
 @userId int,
 @noteType char(1),
 @aCode char(3),
 @bCode char(3), 
 @cCode char(3),
 @outDuplicateFound int OUT
AS
BEGIN

SET @outDuplicateFound = (SELECT Top 1 id FROM codeTable 
                          WHERE userId = @userId
                          AND noteType = @noteType
                          AND COALESCE(aCode,'NUL') = COALESCE(@aCode,'NUL')
                          AND COALESCE(bCode,'NUL') = COALESCE(@bCode,'NUL')
                          AND COALESCE(cCode,'NUL') = COALESCE(@cCode,'NUL')
                          )
-- Now set the duplicate output flag to a 1 or a 0
IF (@outDuplicateFound IS NULL) OR (@outDuplicateFound = '') OR (@outDuplicateFound = 0)
 SET @outDuplicateFound = 0
ELSE 
 SET @outDuplicateFound = 1
END

祝你好运!

杰森

于 2008-12-19T13:32:07.547 回答
0

我将首先添加一个检查以查看所有参数在运行时是否为空,即

IF(COALESCE(@userId, @noteType, @aCode, @bCode, @cCode) IS NULL)
   BEGIN
       -- do something here, log, print, return, etc.
   END

然后在您验证用户传递了某些内容之后,您可以在 WHERE 子句中使用类似的内容

WHERE userId = COALESCE(@userId, userId)
AND noteType = COALESCE(@noteType, noteType)
AND aCode    = COALESCE(@aCode, aCode)
AND bCode    = COALESCE(@bCode, bCode)
AND cCode    = COALESCE(@cCode, cCode)

编辑:我可能错过了如果参数作为 null 传入的意图,这意味着您明确想要测试该列是否为 null。我上面的 where 子句假设 null 参数意味着“跳过此列的测试”。

或者,我相信您可以使用原始查询并在存储过程创建时添加 ANSI_NULLS 设置选项。例如,

SET ANSI_NULLS OFF
GO
CREATE PROC sp_myDuplicateCheck....

实际上,这应该允许您的代码评估 column=null 而不是 column is null。我认为 Kalen Delaney 曾经将 ANSI _NULLS 和 QUOTED_IDENTIFIER选项创造为“粘性选项”,因为如果它们是在过程创建时设置的,它们会在运行时与过程保持一致,而不管当时的连接是如何设置的。

于 2008-12-19T13:22:55.787 回答
0

试试这个 :

CREATE PROCEDURE sp_myDuplicateCheck
     @userId int = 0,
     @noteType char(1) = "",
     @aCode char(3) = "", 
     @bCode char(3) = "", 
     @cCode char(3) = "",
     @outDuplicateFound int OUT
    AS
    BEGIN
    SET @outDuplicateFound = (SELECT Top 1 id FROM codeTable 
                              WHERE @userId in (userId ,0)
                              AND @noteType in (noteType,"")
                              AND @aCode in (aCode , "")
                              AND @bCode in (bCode , "")
                              AND @cCode in (cCode ,"")
                              )
    -- Now set the duplicate output flag to a 1 or a 0
    IF (@outDuplicateFound IS NULL) OR (@outDuplicateFound = '') OR (@outDuplicateFound = 0)
     SET @outDuplicateFound = 0
    ELSE 
     SET @outDuplicateFound = 1
    END

这基本上是在 null 的情况下为输入参数提供默认值,然后在 where 条件下在值不等于默认值时检查。

于 2008-12-19T13:31:02.947 回答
0

SET ANSI_NULLS OFF/On

这样你就可以做到colName = null

于 2010-06-18T15:34:36.543 回答