Jus*_*tin 69 sql-server stored-procedures data-access
我有一个存储过程有一堆输入和输出参数,因为它是将值插入多个表.在某些情况下,存储过程仅插入到单个表中(取决于输入参数).这是一个模拟的场景来说明.
表/数据对象:
人
Id
Name
Address
Run Code Online (Sandbox Code Playgroud)
名称
Id
FirstName
LastName
Run Code Online (Sandbox Code Playgroud)
地址
Id
Country
City
Run Code Online (Sandbox Code Playgroud)
假设我有一个插入人的存储过程.如果地址不存在,我将不会将其添加到Address数据库中的表.
因此,当我生成调用存储过程的代码时,我不想打扰添加Address参数.对于INPUT参数,这是可以的,因为SQL Server允许我提供默认值.但是对于OUTPUT参数我在存储过程中做什么使它成为可选的,所以我没有收到错误...
过程或函数'Person_InsertPerson'需要参数'@AddressId',这是未提供的.
Phi*_*ley 108
输入和输出参数都可以分配默认值.在这个例子中:
CREATE PROCEDURE MyTest
@Data1 int
,@Data2 int = 0
,@Data3 int = null output
AS
PRINT @Data1
PRINT @Data2
PRINT isnull(@Data3, -1)
SET @Data3 = @Data3 + 1
RETURN 0
Run Code Online (Sandbox Code Playgroud)
第一个参数是必需的,第二个和第三个是可选的 - 如果没有被调用例程设置,它们将被分配默认值.尝试使用不同的值和设置来解决SSMS中的以及以下测试调用例程,以了解它们如何一起工作.
DECLARE @Output int
SET @Output = 3
EXECUTE MyTest
@Data1 = 1
,@Data2 = 2
,@Data3 = @Output output
PRINT '---------'
PRINT @Output
Run Code Online (Sandbox Code Playgroud)
esc*_*llc 13
输出参数和默认值不能很好地协同工作!这来自SQL 10.50.1617(2008 R2). 不要被愚弄相信这个结构神奇地SET代表你做这个价值(就像我的同事那样)!
这个"玩具"SP询问OUTPUT参数值,无论它是默认值还是NULL.
CREATE PROCEDURE [dbo].[omgwtf] (@Qty INT, @QtyRetrieved INT = 0 OUTPUT)
AS
IF @QtyRetrieved = 0
BEGIN
print 'yay its zero'
END
IF @QtyRetrieved is null
BEGIN
print 'wtf its NULL'
END
RETURN
Run Code Online (Sandbox Code Playgroud)
如果你发送了一个未初始化的值(即NULL)OUTPUT,你真的NULL进入了SP,而不是0.有道理,为该参数传递了一些东西.
declare @QR int
exec [dbo].[omgwtf] 1, @QR output
print '@QR=' + coalesce(convert(varchar, @QR),'NULL')
Run Code Online (Sandbox Code Playgroud)
输出是:
wtf its NULL
@QR=NULL
Run Code Online (Sandbox Code Playgroud)
如果我们SET从调用者添加一个显式,我们得到:
declare @QR int
set @QR = 999
exec [dbo].[omgwtf] 1, @QR output
print '@QR=' + coalesce(convert(varchar, @QR),'NULL')
Run Code Online (Sandbox Code Playgroud)
和(不足为奇的)输出:
@QR=999
Run Code Online (Sandbox Code Playgroud)
同样,有意义的是,传递了一个参数,并且SP没有对SET值进行任何显式操作.
添加SET了的OUTPUT参数在SP(像你应该做的),但是没有设置从呼叫者什么:
ALTER PROCEDURE [dbo].[omgwtf] (@Qty INT, @QtyRetrieved INT = 0 OUTPUT)
AS
IF @QtyRetrieved = 0
BEGIN
print 'yay its zero'
END
IF @QtyRetrieved is null
BEGIN
print 'wtf its NULL'
END
SET @QtyRetrieved = @Qty
RETURN
Run Code Online (Sandbox Code Playgroud)
现在执行时:
declare @QR int
exec [dbo].[omgwtf] 1234, @QR output
print '@QR=' + coalesce(convert(varchar, @QR),'NULL')
Run Code Online (Sandbox Code Playgroud)
输出是:
wtf its NULL
@QR=1234
Run Code Online (Sandbox Code Playgroud)
这是OUTPUTSP中参数处理的"标准"行为.
现在对于情节扭曲:获取默认值为"激活"的唯一方法是根本不传递OUTPUT参数,恕我直言就没有意义:因为它被设置为OUTPUT参数,这意味着返回"重要"的东西应该收集.
declare @QR int
exec [dbo].[omgwtf] 1
print '@QR=' + coalesce(convert(varchar, @QR),'NULL')
Run Code Online (Sandbox Code Playgroud)
给出这个输出:
yay its zero
@QR=NULL
Run Code Online (Sandbox Code Playgroud)
但这无法捕获SP的输出,可能是该SP开始的目的.
恕我直言这个功能组合是一个可疑的构造我会考虑代码气味(p !!)
看起来我可以为OUTPUT参数添加默认值,例如:
@AddressId int = -1 Output
Run Code Online (Sandbox Code Playgroud)
看起来它的可读性很差,因为AddressId它严格地作为一个OUTPUT变量。但它有效。如果您有更好的解决方案,请告诉我。
| 归档时间: |
|
| 查看次数: |
71373 次 |
| 最近记录: |