如何将NULL限制为存储过程SQL Server的参数?

Sha*_*bie 36 sql sql-server stored-procedures

是否可以创建存储过程

CREATE PROCEDURE Dummy 
    @ID INT NOT NULL
AS
BEGIN
END
Run Code Online (Sandbox Code Playgroud)

为什么不可能做这样的事情?

Uns*_*ced 46

您可以在sproc中检查其NULL-ness RAISERROR并将状态报告回调用位置.

CREATE   proc dbo.CheckForNull @i int 
as
begin
  if @i is null 
    raiserror('The value for @i should not be null', 15, 1) -- with log 

end
GO
Run Code Online (Sandbox Code Playgroud)

然后打电话:

exec dbo.CheckForNull @i = 1 
Run Code Online (Sandbox Code Playgroud)

要么

exec dbo.CheckForNull @i = null 
Run Code Online (Sandbox Code Playgroud)


Pat*_*erg 14

你的代码是正确的,合理的,甚至是良好的实践.您只需要等待支持这种语法的SQL Server 2014.

毕竟,为什么在编译时可以在运行时捕获?

另请参阅此msdn文档Natively Compiled在那里搜索.

正如dkrez所说,nullabiliy不被视为数据类型定义的一部分.我仍然想知道为什么不.


dkr*_*etz 0

参数验证目前不是 SQL Server 中过程逻辑的一项功能,NOT NULL 只是一种可能的数据验证类型。表中的 CHAR 数据类型具有长度规范。这也应该实施吗?以及如何处理异常情况?对于表模式中的异常处理,有一种广泛的、高度发达的、某种程度上基于标准的方法;但不适用于过程逻辑,可能是因为过程逻辑是从关系系统中定义的。另一方面,存储过程已经具有引发错误事件的现有机制,并与众多 API 和语言相关联。对于参数的声明性数据类型约束没有这样的支持。添加它的影响是广泛的;特别是因为它得到了良好的支持并且可扩展,只需添加代码即可:

IF ISNULL(@param) THEN
    raise error ....
END IF
Run Code Online (Sandbox Code Playgroud)

存储过程上下文中的 NULL 概念甚至没有明确定义,特别是与表或 SQL 表达式的上下文相比。而且这不是微软的定义。SQL 标准组花费了很多年的时间生成了大量文献来建立 NULL 的行为以及该行为的定义范围。存储过程不是其中之一。

存储过程被设计得尽可能轻量,以使数据库性能尽可能高效。参数的数据类型不是为了验证,而是为了使编译器能够为查询优化器提供更好的信息,以编译最佳的查询计划。参数上的 NOT NULL 约束会导致编译器变得更加复杂,以实现验证参数的新目的。因此效率较低且较重。

存储过程不被编写为 C# 函数是有原因的。

  • *“为什么它应该是可能的”* - 嗯...因为它是`CREATE TABLE`语句中非常常用的快捷方式,所以*不*将它用于`CREATE PROCEDURE`是不一致的?对于 SQL Server 来说,以与检查表列完全相同的方式检查参数是否为 null 有多困难? (48认同)
  • NOT NULL 不是数据类型的一部分。它是表的列定义的一部分。NULL 是无类型的。没有 NULL INTEGER 或 NULL VARCHAR 这样的概念。是的,它是用于断言表中列的 DDL 的一部分。DEFAULT 也是如此,索引和外键定义也是如此。我们是说存储过程参数被视为与表列正交吗? (3认同)