简体   繁体   English

如何将NULL传递给具有NON-NULL默认值的SQL Server存储过程参数

[英]How to pass null to SQL Server stored procedure param with NON-NULL default value

I have a SQL Server stored procedure inside a multi-tenant DB. 我在多租户数据库中有一个SQL Server存储过程。 It is used by all clients, but since I don't update them all at the same time I needed to provide default parameter values so clients wouldn't throw an error if they didn't pass in the parameter. 所有客户端都使用它,但是由于我不会同时更新所有客户端,因此我需要提供默认参数值,这样,如果客户端没有传入参数,它们就不会抛出错误。

It looks like this: 看起来像这样:

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'  

I couldn't use null as the default value because null is a valid value to pass in (to clear out a search index). 我不能使用null作为默认值,因为null是要传入的有效值(以清除搜索索引)。 However, when I assign a parameter to DBNull.Value , it seems that the stored procedure thinks nothing is passed and the stored procedure then uses the default 'BTR:NOSEARCHUPDATE' in its logic and does nothing (instead of clearing out the value) - if I assign DBNull, the != 'BTR;NOSEARCHUPDATE' below evaluates to false. 但是,当我将参数分配给DBNull.Value ,似乎存储过程认为未传递任何内容 ,然后该存储过程在其逻辑中使用默认的'BTR:NOSEARCHUPDATE'并且不执行任何操作(而不是清除值)-如果我分配DBNull,则下面的!='BTR; NOSEARCHUPDATE'评估为false。

CASE WHEN @pSearch01 != 'BTR:NOSEARCHUPDATE' THEN @pSearch01 ELSE pSearch01 END,

This statement is simply trying to get the value of the parameter if 'something was passed in (DBNull or value)', otherwise fall back to the existing value in the the corresponding db field. 如果“传入了某些内容(DBNull或值)”,则此语句只是试图获取参数的值,否则返回对应的db字段中的现有值。

I assign DBNull using the following code: 我使用以下代码分配DBNull

UpdateCommand.Parameters[ "@pSearch19" ].Value = DBNull.Value;

So the question is, how can I pass in 'null' to the stored procedure so that it uses that as the value instead of simply using the default value 'BTR:NOSEARCHUPDATE'? 因此,问题是,如何将“ null”传递给存储过程,以使其将其用作值,而不是简单地使用默认值“ BTR:NOSEARCHUPDATE”?

null is a valid value to pass, and it won't be overridden by the default parameter value. null是要传递的有效值,并且不会被默认参数值覆盖。 I can't repro this behavior in T-SQL or ADO.NET. 我无法在T-SQL或ADO.NET中复制此行为。

EG for EG为

create or 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' 
as
begin
    select @pSearch01 search01
end

then in .NET 然后在.NET中

using (var con = new SqlConnection("server=.;database=tempdb;integrated security=true"))
{
   con.Open();

   SqlCommand cmd = con.CreateCommand();
   cmd.CommandText = "sp_UpdateSearchValues";
   cmd.CommandType = System.Data.CommandType.StoredProcedure;

   var pAuthID = cmd.Parameters.Add("@pAuthID", SqlDbType.NVarChar,255 );
   var pgKey = cmd.Parameters.Add("@pgKey", SqlDbType.Int);
   var pSearch01 = cmd.Parameters.Add("@pSearch01", SqlDbType.NVarChar, 255);

   pAuthID.Value = "a";
   pgKey.Value = 1;
   pSearch01.Value = DBNull.Value;

   var r = cmd.ExecuteScalar();

   Console.WriteLine($"{r} {r.GetType().Name}");

   Console.ReadKey();
}

Outputs 输出

DBNull

But it looks like this is a simple case of null comparison and 3-valued logic. 但这看起来像是空比较和三值逻辑的简单情况。

Consider: 考虑:

declare @pSearch01 nvarchar(200) = null
select CASE WHEN @pSearch01 != 'BTR:NOSEARCHUPDATE' then 1 else 0 end

What does that return? 那会返回什么? Is null != 'BTR:NOSEARCHUPDATE' a true statement? null != 'BTR:NOSEARCHUPDATE'是真实的语句吗? No it's not. 不,这不对。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM