Как передать null в параметр хранимой процедуры SQL Server со значением NON-NULL по умолчанию - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть хранимая процедура 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 или value)», в противном случае вернитесь к существующему значению в соответствующем поле db.

Я присваиваю DBNull, используя следующий код:

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

Таким образом, вопрос в том, как я могу передать 'null' хранимой процедуре, чтобы она использовала ее в качестве значения вместо простого использования значения по умолчанию 'BTR: NOSEARCHUPDATE'?

1 Ответ

0 голосов
/ 07 февраля 2019

null - допустимое значение для передачи, и оно не будет переопределено значением параметра по умолчанию.Я не могу воспроизвести это поведение в T-SQL или ADO.NET.

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

, затем в .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();
}

Выходы

DBNull

Но, похоже, это простой случай нулевого сравнения и 3-значной логики.

Подумайте:

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

Что это возвращает?Является ли null != 'BTR:NOSEARCHUPDATE' верным утверждением?Нет, это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...