Использую в хранимке табличный тип:
CREATE PROCEDURE dbo.p_TestProc
@UID INT =0,
@RequredID StringTableType READONLY
Где StringTableType табличный тип определяемый следующим образом:
CREATE TYPE dbo.StringTableType AS TABLE (
StrValue VARCHAR(50) COLLATE Cyrillic_General_CI_AS NULL
)
Вопрос: Как сделать параметр @RequredID необязательным?
Или, как альтернатива: Как определить для @RequredID значение по умолчанию? (не пустое, а скажем чтобы таблице была одна строка со значением "EMPTY")
Ответ
Переменные табличного типа итак необязательны.
Можно вызвать:
exec dbo.p_TestProc @UID = 1
в этом случае @RequiredID примет значение пустой таблицы.
Значение по умолчанию, насколько мне известно, задать нельзя, т.е. написать что-то типа
CREATE PROCEDURE dbo.p_TestProc
(
@UID INT = 0,
@RequiredID StringTableType READONLY = VALUES ('EMPTY')
)
не выйдет.
Если нет возможности контролировать вызов процедуры, то можно внутри кода процедуры вместо входного параметра попробовать использовать дополнительную переменную того же табличного типа, в которую перекладывать данные из входного параметра, или инициализировать её по необходимости значениями по-умолчанию. Примерно так:
ALTER PROCEDURE dbo.p_TestProc
(
@UID INT = 0,
@RequiredID StringTableType READONLY
)
as
begin
set nocount on;
declare @NormalizedID StringTableType;
if exists (select 1 from @RequiredID)
insert into @NormalizedID (StrValue)
select StrValue from @RequiredID;
else
insert into @NormalizedID (StrValue)
values ('EMPTY');
-- далее по коду использовать @NormalizedID вместо @RequiredID
-- ...
end
Хотя, конечно такое перекладывание данных не слишком изящно и несколько снизит производительность.
Если же вы контролируете вызов, то оптимальнее всё же задать умолчания до вызова процедуры, а не внутри неё.
В SQL коде это будет примерно так:
declare @uid int;
declare @tableParam dbo.StringTableType;
select @uid = ID from SomeTable where ...;
insert into @tableParam (StrValue)
select SomeValue
from SomeOtherTable
where ...;
if not exists (select 1 from @tableParam)
insert into @tableParam (StrValue)
values ('EMPTY');
exec dbo.p_TestProc @uid, @tableParam;
Если же это внешний вызов, то, например, на C# это будет выглядеть примерно следующим образом:
class StringTableType : DataTable
{
public StringTableType()
{
Columns.Add("StrValue", typeof(string));
}
public static StringTableType GetDefault()
{
var def = new StringTableType();
def.Rows.Add("EMPTY");
return def;
}
}
void Call_p_TestProc(int? uid, StringTableType t)
{
SqlCommand cmd = new SqlCommand("dbo.p_TestProc");
cmd.Parameters.AddWithValue("@UID", uid ?? (object)DBNull.Value);
cmd.Parameters.Add(
new SqlParameter("@tableParam", SqlDbType.Structured)
{
TypeName = "[dbo].[StringTableType]",
Value = t == null || t.Rows.Count == 0 ? StringTableType.GetDefault() : t
});
//execute cmd
}
Комментариев нет:
Отправить комментарий