在存储过程中使用带有可选参数的UPDATE

Dis*_*oat 23 sql-server stored-procedures

我有一个像这样的SP(使用SQL Server):

ALTER PROCEDURE [dbo].[sp_ClientNotes_update]
    @id uniqueidentifier,
    @ordering smallint = NULL,
    @title nvarchar(20) = NULL,
    @content text = NULL
AS
BEGIN
    SET NOCOUNT ON;
    UPDATE tbl_ClientNotes
    SET ordering=@ordering, title=@title, content=@content
    WHERE id=@id
END
Run Code Online (Sandbox Code Playgroud)

我想只在它们被传递到SP时设置值,即不是NULL.可以这样做吗?

这个问题似乎表明唯一的方法是使用完全独立的条件查询,但对于3个可选参数,这显然是一场噩梦!

Chr*_*ver 41

试试这个.

ALTER PROCEDURE [dbo].[sp_ClientNotes_update]
    @id uniqueidentifier,
    @ordering smallint = NULL,
    @title nvarchar(20) = NULL,
    @content text = NULL
AS
BEGIN
    SET NOCOUNT ON;
    UPDATE tbl_ClientNotes
    SET ordering=ISNULL(@ordering,ordering), 
        title=ISNULL(@title,title), 
        content=ISNULL(@content, content)
    WHERE id=@id
END
Run Code Online (Sandbox Code Playgroud)

WHERE如果你使用事务复制,它也可能值得为该子句添加一个额外的部分,那么如果所有都是NULL,它将向订阅者发送另一个更新,以防止这种情况发生.

WHERE id=@id AND (@ordering IS NOT NULL OR
                  @title IS NOT NULL OR
                  @content IS NOT NULL)
Run Code Online (Sandbox Code Playgroud)

  • 这不是最佳实践,即主观偏好,因为"COALESCE"是ANSI.这两种功能的行为都不同,说你应该总是使用一种,因为最佳做法是错误的.但在这种情况下,他们的行为是一样的. (3认同)
  • @chris实际上,`ISNULL`在这里是正确的,因为任何这些字段都可以为空.如果存储过程中的参数为null,并且该字段的当前值也为null,则不会向"COALESCE"函数提供至少一个非空值的错误.所以是的,你使用`ISNULL`是正确的,但在这种情况下它们的行为不一样. (2认同)
  • @Noah我刚刚检查过这个,你从`COALESCE(NULL,NULL)`获得的错误是其中一个参数必须是一个类型为null.微妙的差异.因为输入的参数应该没问题.如果你做`DECLARE @test INT = NULL; SELECT COALESCE(@test,NULL)然后它不会抛出错误,因为`@ test`是一个`INT`.两者推断返回类型的方式不同,这是行为不同的原因之一.MSDN上有相当多的细节http://msdn.microsoft.com/en-gb/library/ms190349.aspx (2认同)