【发布时间】:2010-09-24 17:22:33
【问题描述】:
是否可以创建存储过程为
CREATE PROCEDURE Dummy
@ID INT NOT NULL
AS
BEGIN
END
为什么不能做这样的事情?
【问题讨论】:
标签: sql sql-server stored-procedures
是否可以创建存储过程为
CREATE PROCEDURE Dummy
@ID INT NOT NULL
AS
BEGIN
END
为什么不能做这样的事情?
【问题讨论】:
标签: sql sql-server stored-procedures
您可以在 sproc 和 RAISERROR 中检查其是否为 NULL,以将状态报告回调用位置。
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
【讨论】:
您的代码是正确的、明智的,甚至是良好的实践。你只需要等待支持这种语法的SQL Server 2014。
毕竟,既然可以在编译时捕获,为什么还要在运行时捕获呢?
另请参阅this Microsoft document 并在其中搜索Natively Compiled。
正如 dkrez 所说,可空性不被视为数据类型定义的一部分。我仍然想知道为什么不。
【讨论】:
哦,好吧,我似乎无法编辑 @Unsliced 帖子,因为“此编辑偏离了帖子的原始意图。即使是必须做出重大改变的编辑也应该努力保持帖子所有者的目标。”。
所以(@crokusek 和所有感兴趣的人)这是我提出的解决方案:
您可以在 sproc 和 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
【讨论】:
您可能需要这种语法的一个原因是,当您在 C# 数据集 GUI 向导中使用 sp 时,如果没有 null 限制,它会创建带有可为 null 参数的函数。 sp body 中没有 null 检查会有所帮助。
【讨论】:
参数验证目前不是 SQL Server 中过程逻辑的一项功能,NOT NULL 只是一种可能的数据验证类型。表中的 CHAR 数据类型具有长度规范。是否也应该实施?以及如何处理异常?对于表模式中的异常处理,有一种广泛的、高度开发的和基于标准的方法;但不适用于程序逻辑,可能是因为程序逻辑是在关系系统之外定义的。另一方面,存储过程已经具有引发错误事件的现有机制,并与众多 API 和语言相关联。对参数的声明性数据类型约束没有这种支持。添加它的含义是广泛的;特别是因为它得到很好的支持和可扩展,只需添加代码:
IF ISNULL(@param) THEN
raise error ....
END IF
与表或 SQL 表达式的上下文相比,存储过程上下文中的 NULL 概念甚至都没有明确定义。这不是微软的定义。 SQL 标准组花费了很多年的时间来编写大量文献来确定 NULL 的行为以及该行为的定义范围。存储过程不是其中之一。
存储过程被设计为尽可能轻量级,以使数据库性能尽可能高效。参数的数据类型不是为了验证,而是为了使编译器能够为查询优化器提供更好的信息,以编译最佳的查询计划。参数上的 NOT NULL 约束通过使编译器更复杂以实现验证参数的新目的而走向另一条路径。因此效率较低且较重。
存储过程不写成 C# 函数是有原因的。
【讨论】:
CREATE TABLE 语句中非常常用的快捷方式,所以不是 将它用于CREATE PROCEDURE 不一致? SQL Server 以与表列完全相同的方式检查参数是否为 null 有多难?