是否可以将存储过程创建为
CREATE PROCEDURE Dummy
@ID INT NOT NULL
AS
BEGIN
END
为什么不可能做这样的事情?
答案 0 :(得分:45)
您可以在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
然后致电:
exec dbo.CheckForNull @i = 1
或
exec dbo.CheckForNull @i = null
答案 1 :(得分:14)
您的代码是正确的,合理的,甚至是良好的做法。您只需要等待支持这种语法的 SQL Server 2014 。
毕竟,为什么在编译时可以在运行时捕获?
另请参阅this msdn document并在那里搜索Natively Compiled
。
正如dkrez所说,nullabiliy不被视为数据类型定义的一部分。我仍然想知道为什么不。
答案 2 :(得分:0)
哦,看来我无法编辑@Unsliced帖子,因为“此编辑偏离了帖子的初衷。即使必须进行重大更改的编辑也应努力维护帖子所有者的目标。”
所以(@crokusek和每个感兴趣的人),这是我提出的解决方案:
您可以在proc和RAISERROR
中检查其NULL值,以将状态报告回调用位置。
CREATE proc dbo.CheckForNull
@name sysname = 'parameter',
@value sql_variant
as
begin
if @value is null
raiserror('The value for %s should not be null', 16, 1, @name) -- with log
end
GO
然后致电:
exec dbo.CheckForNull @name 'whateverParamName', @value = 1
或
exec dbo.CheckForNull @value = null
答案 3 :(得分:0)
之所以可能需要这种语法的一个原因是,当在C#数据集GUI向导中使用sp时,如果没有null限制,它将创建具有nullable参数的函数。 sp主体中没有null检查就可以解决问题。
答案 4 :(得分:-5)
参数验证目前不是SQL Server中过程逻辑的一个特性,NOT NULL只是一种可能的数据验证类型。表中的CHAR数据类型具有长度规范。是否应该实施?你如何处理异常?在表格模式中有一种广泛的,高度发展的,基于标准的方法用于异常处理;但不是程序逻辑,可能是因为程序逻辑是由关系系统定义的。另一方面,存储过程已经存在用于引发错误事件的现有机制,其与许多API和语言相关联。对参数的声明性数据类型约束没有这种支持。添加它的含义是广泛的;特别是因为只需添加代码就可以很好地支持和扩展:
IF ISNULL(@param) THEN
raise error ....
END IF
与表或SQL表达式的上下文相比,存储过程上下文中的NULL概念甚至没有明确定义。这不是微软的定义。 SQL标准组花了很多年时间生成了大量文献,建立了NULL的行为以及该行为定义的界限。并且存储过程不是其中之一。
存储过程旨在尽可能轻量级,以使数据库性能尽可能高效。参数的数据类型不是用于验证,而是为了使编译器能够为查询优化器提供更好的信息,以便编译最佳的查询计划。通过使编译器对于验证参数的新目的更复杂,对参数的NOT NULL约束沿着整个路径向下。因此效率更低,更重。
存储过程没有写成C#函数的原因。