传递默认参数值与根本不传递参数?
Posted
技术标签:
【中文标题】传递默认参数值与根本不传递参数?【英文标题】:Passing default parameter value vs not passing parameter at all? 【发布时间】:2009-05-07 21:35:57 【问题描述】:这是我想做的:
给定一张桌子
PeopleOutfit (id int primary key, boots int, hat int)
还有一个存储过程
UpdateOutfit @id int, @newBoots int = null, @newHat = null
有没有办法判断我是否将此过程称为
exec UpdateOutfit @id=1, @newBoots=null, @newHat=5
有效地告诉 id 为 1 的人现在必须赤脚并戴上第五顶帽子
exec UpdateOutfit @id=1, @newHat=5
这指示此人戴上第五顶帽子,保持他现在的靴子?
换句话说,我想告诉(在存储过程中)是否“使用了默认值,因为它没有被指定”从“我显式调用这个过程传递的值恰好与默认值相同” .
我知道有几种方法可以完成我想做的事情,例如传递要更新的字段的 XML 或位掩码,但目前我只想确定这种确切的技术是否可行。
编辑:传递保留值不适用于具有小范围类型(例如位)的字段。重载过程也是一个不可接受的选项。创建用户定义的类型,使用附加的“NotAValue”值扩展 NULL 范式可能是一个答案,但我需要更多关于如何实现它的指导。
【问题讨论】:
【参考方案1】:我的猜测是不,你无法区分这两件事。
我的建议是使用一个您永远不会作为参数传入的默认值。即,如果默认值为null
,那么也许您可以传入0
作为@newBoots
的值
【讨论】:
是的,这是一种方式,但这会是位域的问题。【参考方案2】:不,默认的 null“看起来”与传入的 null 相同
可能将您的默认值设为 -1 并使用逻辑来做一些不同的事情。
【讨论】:
【参考方案3】:严格来说,不,没有真正的设施可以做到这一点。但是,您可以尝试为参数使用某种保留值(例如非常小的负数)来表示这一点。
【讨论】:
【参考方案4】:我自己从来没有这样做过;在一些代码中引入了 3 状态位(使用整数)来处理位情况。我无法访问 sql 服务器,但有时我确实喜欢后期思考;但我认为您可能能够通过一些管理视图/功能找出 ysubg 字符串操作。您需要以大量特权运行,但如果绝对有必要,我不明白为什么您不能使用类似这样的东西从 st.text 解决它
SELECT
st.text
FROM
sys.dm_exec_requests r
CROSS APPLY
sys.dm_exec_sql_text(sql_handle) AS st
WHERE
r.session_id = @@SPID
【讨论】:
嗯...我不完全理解你的建议,但我想我有这个想法,这个想法就是反思。我的问题的真正目的是减少开销,因此复杂的子查询不是答案,因为对此有成本更低的解决方案。无论如何都是好主意! 他说的是检索实际执行的 TSQL 语句。 SQL Server 记录所有执行的 SQL 命令,您可以从系统视图中看到它们。不幸的是,他提供的视图返回了编译后的语句——所以在存储过程中,你得到的只是存储过程定义,而不是调用代码。【参考方案5】:如上所述,TSQL 不区分提供默认值和不提供值。我认为引擎基本上会用默认值替换任何缺失的参数(或使用 DEFAULT 关键字调用的参数。)
相反,使用 0 作为“No Hat”,使用 NULL 作为未指定参数。这是 NULL 的首选用法,它表示值未知或未指定。通过将 NULL 用作“No Hat”,您已经选择将它添加到您的数据类型范围中添加一个额外的值。
从 BIT 数据类型的角度来考虑它。数据类型被定义为表示二进制值(1 或 0,或 T/F,如果您更愿意将其视为布尔值。)通过将 NULL 视为有效值,您已将数据类型扩展到二进制选项之外(现在有三个选项,1/0/NULL。)我的建议始终是,如果您发现当前数据类型中的值已用完,则说明您使用的类型太小了。
回到存储过程调用;如果您将默认值设置为 NULL,并将 NULL 视为未设置或未指定,则调用者在调用 proc 时应始终指定非空值。如果你得到一个 NULL,假设他们没有提供一个值,提供了一个 NULL,或者使用了 DEFAULT 关键字。
【讨论】:
以上是关于传递默认参数值与根本不传递参数?的主要内容,如果未能解决你的问题,请参考以下文章