Как определить, было ли передано значение параметра хранимой процедуре

Я хочу создать хранимую процедуру (в SQL Server 2008 R2), которая будет обновлять запись в таблице на основе PK таблицы.

Сохраненный процесс будет иметь, например, четыре параметра:

@ID int,
@Name nvarchar(50),
@Email nvarchar(80),
@Phone nvarchar(20)

Как я могу определить, передает ли вызывающая сторона хранимого процесса значение NULL для одного (или нескольких) параметров по сравнению с тем, не передает ли вызывающая сторона ничего для одного (или нескольких) параметров?

Пример вызывающего абонента С#:

Вызывающий указывает NULL для @Phone:

using (SqlCommand cmd = new SqlCommand())
{
  cmd.CommandType = System.Data.CommandType.StoredProcedure;
  cmd.CommandText = "EditPerson";
  cmd.Parameters.AddWithValue("@ID", id);
  cmd.Parameters.AddWithValue("@Name", 'Frank');
  cmd.Parameters.AddWithValue("@Email", '[email protected]');
  cmd.Parameters.AddWithValue("@Phone", DBNull.Value);
  DatabaseManager.instance.ExecuteScalarQuery(cmd);
}

Вызывающий игнорирует параметр @Phone:

using (SqlCommand cmd = new SqlCommand())
{
   cmd.CommandType = System.Data.CommandType.StoredProcedure;
   cmd.CommandText = "EditPerson";
   cmd.Parameters.AddWithValue("@ID", id);
   cmd.Parameters.AddWithValue("@Name", 'Frank');
   cmd.Parameters.AddWithValue("@Email", '[email protected]');
   DatabaseManager.instance.ExecuteScalarQuery(cmd);
}

Что я пытаюсь здесь сделать, так это то, что если вызывающая сторона явно указывает значение NULL для параметра, я обновлю запись значением NULL. Однако, если пользователь явно игнорирует передачу параметра, то запрос UPDATE сохранит значение поля/столбца, которое уже установлено для конкретной записи (т. е. запрос НЕ будет обновлять этот конкретный столбец).

Я полагаю, что мог бы указать значения по умолчанию, которые можно с уверенностью предположить, что вызывающая сторона никогда не будет их использовать - что-то вроде этого:

@ID int,
@Name nvarchar(50) = 'NameIsUndefined',
@Email nvarchar(80) = 'EmailIsUndefined',
@Phone nvarchar(20) = 'PhoneIsUndefined'

Затем в хранимой процедуре я могу проверить неопределенные значения - если переменные параметров все еще установлены на значения NameIsUndefined, EmailIsUndefined и/или PhoneIsUndefined, то я могу с уверенностью предположить, что вызывающая сторона явно не определила значения для этих параметров. . Это единственный способ достичь моей цели?


person Jed    schedule 12.08.2011    source источник
comment
Да, вам нужно использовать значение, отличное от NULL, для представления другого состояния. Поэтому либо установите значение по умолчанию, отличное от NULL, либо передайте значение, отличное от NULL. Выберите, хотите ли вы, чтобы NULL или какое-либо другое значение указывало, что значение не было передано.   -  person nekno    schedule 12.08.2011


Ответы (2)


Невозможно определить разницу между NULL и NULL в SQL Server, насколько мне известно.

В вашем коде С# я бы: а) передал другое значение, например пустую строку, чтобы указать, что было передано пустое значение, а затем обработал его в SQL, чтобы записать NULL в БД, если значение было передано, или сохранить предыдущее значение, если переменная имеет значение NULL или B) Вместо передачи DBNull.Value передать предыдущее значение, которое было прочитано из БД.

person nekno    schedule 12.08.2011

Если вы объявите свои параметры таким образом (без значения по умолчанию), хранимая процедура потребует все четыре из них и просто завершится ошибкой, если какой-либо из них не будет передан оператору EXEC, составленному провайдером.

Вы можете объявить некоторые параметры необязательными, например:

@Phone nvarchar(20) = NULL

однако внутри sproc нельзя будет определить, был ли он опущен или явно установлен на NULL.

person Quassnoi    schedule 12.08.2011