执行存储过程参数验证的"正确"方法

VVS*_*VVS 33 sql sql-server error-handling stored-procedures

我有一个存储过程执行一些参数验证,如果参数无效,应该失败并停止执行.

我的第一个错误检查方法如下所示:

create proc spBaz
(
  @fooInt int = 0,
  @fooString varchar(10) = null,
  @barInt int = 0,
  @barString varchar(10) = null
)
as
begin
  if (@fooInt = 0 and (@fooString is null or @fooString = ''))
    raiserror('invalid parameter: foo', 18, 0)

  if (@barInt = 0 and (@barString is null or @barString = ''))
    raiserror('invalid parameter: bar', 18, 0)

  print 'validation succeeded'
  -- do some work
end
Run Code Online (Sandbox Code Playgroud)

由于严重性18不会停止执行并且"验证成功"与错误消息一起打印,因此这不起作用.

我知道我可以在每次raiserror之后添加一个返回但这对我来说看起来很难看:

  if (@fooInt = 0 and (@fooString is null or @fooString = ''))
  begin
    raiserror('invalid parameter: foo', 18, 0)
    return
  end

  ...

  print 'validation succeeded'
  -- do some work
Run Code Online (Sandbox Code Playgroud)

由于严重性为11或更高的错误在try/catch块中被捕获,我测试的另一种方法是将我的错误检查封装在这样的try/catch块中.问题是吞没了错误而根本没有发送给客户端.所以我做了一些研究,找到了重新抛出错误的方法:

  begin try
    if (@fooInt = 0 and (@fooString is null or @fooString = ''))
      raiserror('invalid parameter: foo', 18, 0)

    ...
  end try
  begin catch
    exec usp_RethrowError
    return
  end catch

  print 'validation succeeded'
  -- do some work
Run Code Online (Sandbox Code Playgroud)

我对这种方法仍然不满意,所以我问你:

您的参数验证如何?有没有某种"最佳实践"来做这种检查?

Luk*_*keH 47

我认为没有一种"正确"的方法可以做到这一点.

我自己的偏好与第二个示例类似,但每个参数都有一个单独的验证步骤,并且有更明确的错误消息.

正如你所说,它有点麻烦和丑陋,但代码的意图对于阅读它的人来说是显而易见的,它完成了工作.

IF (ISNULL(@fooInt, 0) = 0)
BEGIN
    RAISERROR('Invalid parameter: @fooInt cannot be NULL or zero', 18, 0)
    RETURN
END

IF (ISNULL(@fooString, '') = '')
BEGIN
    RAISERROR('Invalid parameter: @fooString cannot be NULL or empty', 18, 0)
    RETURN
END
Run Code Online (Sandbox Code Playgroud)

  • @macleojw:他同时检查null和''聪明:) (12认同)
  • 第二个验证器的语法无效:'RAISEERROR'.应该只有一个'e'.有趣的是,在英语中它是正确的,因为'raise + error'有双重'e'但不是MS SQL语言. (8认同)