【发布时间】:2019-02-06 23:28:30
【问题描述】:
我在多租户数据库中有一个 SQL Server 存储过程。它被所有客户端使用,但由于我不会同时更新它们,所以我需要提供默认参数值,这样客户端如果没有传入参数就不会抛出错误。
看起来像这样:
ALTER PROCEDURE [dbo].[sp_UpdateSearchValues]
@pAuthID NVARCHAR(255),
@pgKey INT,
@pSearch01 NVARCHAR(255) = 'BTR:NOSEARCHUPDATE',
@pSearch02 NVARCHAR(255) = 'BTR:NOSEARCHUPDATE',
..
@pSearch30 NVARCHAR(255) = 'BTR:NOSEARCHUPDATE'
我不能使用null 作为默认值,因为null 是一个可以传入的有效值(以清除搜索索引)。但是,当我将参数分配给DBNull.Value 时,似乎存储过程认为什么都没有传递,然后存储过程在其逻辑中使用默认的“BTR:NOSEARCHUPDATE”并且什么都不做(而是清除值)- 如果我分配 DBNull,则下面的 != 'BTR;NOSEARCHUPDATE' 评估为 false。
CASE WHEN @pSearch01 != 'BTR:NOSEARCHUPDATE' THEN @pSearch01 ELSE pSearch01 END,
此语句只是尝试获取参数的值,如果“传入了某些内容(DBNull 或值)”,否则回退到相应 db 字段中的现有值。
我使用以下代码分配DBNull:
UpdateCommand.Parameters[ "@pSearch19" ].Value = DBNull.Value;
所以问题是,如何将“null”传递给存储过程,以便它使用它作为值,而不是简单地使用默认值“BTR:NOSEARCHUPDATE”?
【问题讨论】:
-
ado.net 将在传递 vb.net 'Nothing' 或 c# 'Null' 对象时使用默认值。 DBNull.Value 应该传入一个实际的 DBNull(在@David Browne 的回答中突出显示。在执行语句之前,您的代码中是否发生了其他可能会改变参数值的事情?
-
旁注:您应该不为您的存储过程使用
sp_前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免sp_并使用其他东西作为前缀 - 或者根本不使用前缀! -
@marc_s 是的,我知道 sp_ 前缀。但是代码是 15 年前(错误地)编写的,我无法更改这些 SP 名称。 :(
-
你能用空字符串代替NULL吗?
标签: c# sql sql-server sqlcommand default-parameters