SQL Server / Delphi: как передать список целых чисел в качестве параметра, используя тип табличной переменной?
Я использую DELPHI XE6 с компонентами FireDAC и имеет сервер базы данных SQL Server.
В базе данных у меня есть хранимая процедура, которая принимает два параметра, одно целое число, а затем табличную переменную, которая принимает только один столбец типа целое число.
Переменная таблицы может содержать от нуля до нескольких целых чисел.
Руководитель процедуры:
/*
Declare @Temp dbo.LIP
insert into @Temp
Values(10901), (10902), (10903), (10904), (10905), (10912)
exec [dbo].[sp_lager_PkgList] 19, @Temp
*/
ALTER PROCEDURE [dbo].[sp_lager_PkgList]
@OwnerNo INT,
@LIPVariable dbo.LIP READONLY
AS
BEGIN
Часть с комментариями содержит код, который я использовал, чтобы проверить, что процедура работает нормально - и это так.
В Delphi я сделал так:
procedure TForm1.setUpParams;
var
sLIPNo: string;
ii: Integer;
begin
try
spMain.Prepare;
spMain.Params.ParamByName('@OwnerNo').AsInteger := StrToInt(edtPOwner.Text);
with spMain.Params.ParamByName('@LIPVariable') do
begin
DataType := ftDataSet;
DataTypeName := 'dbo.LIP';//'LGlager_PkgList.@LIPVariable';
end;
fdmtblLIPNo.Active := false;
fdmtblLIPNo.Active := True;
fdmtblLIPNo.BeginBatch();
try
for sLIPNo in mmoPLIPs.Lines do
begin
fdmtblLIPNo.Append;
try
fdmtblLIPNo.FieldByName('LIPNo').AsInteger := StrToInt(sLIPNo);
fdmtblLIPNo.Post;
finally
end;
end;
finally
fdmtblLIPNo.EndBatch;
ii := spMain.Params.ParamByName('@OwnerNo').AsInteger;
mmoDebug.Lines.Add(IntToStr(ii));
end;
spMain.ParamByName('@LipVariable').AsDataSet := fdmtblLIPNo;
finally
end;
end;
Когда я позже выполню эту процедуру в программе delphi, ни один из параметров не будет передан. Я проверил, что процедура выполняется так, что часть работает.
Что я делаю неправильно? Что я должен делать?
Это скрипт для dbo.LIP, это не ракетостроение.
CREATE TYPE [dbo].[LIP] AS TABLE(
[LIPNo] [int] NULL
)
1 ответ
То, что вам нужно, это передать массив (это поможет с запросом Google), как вы можете передать массив в SQL Server через определенные пользователем типы таблиц.
Вот пример: https://msdn.microsoft.com/en-us/library/bb386954(v=vs.100).aspx
Это близко:
/*
Declare @Temp dbo.LIP
insert into @Temp
Values(10901), (10902), (10903), (10904), (10905), (10912)
exec [dbo].[sp_lager_PkgList] 19, @Temp
*/
ALTER PROCEDURE [dbo].[sp_lager_PkgList]
@OwnerNo INT,
@LIPVariable dbo.LIP READONLY
Можете ли вы опубликовать DDL для dbo.LIP?
Также вы захотите запустить Profiler и отследить вызов usp_, это покажет вам, что вы передаете usp_ для проверки того, что вы передаете, тогда вы узнаете, есть ли у вас проблемы с SQL или кодом вашего приложения.
Из вашего кода, если вы можете запустить его локально, и он работает, то, скорее всего, у вас нет проблемы с SQL, Profiler ответит на ваш вопрос, также вы можете использовать fiddler, если это проще.
Венгерская нотация часто является плохой практикой, для триггеров и пользовательских хранимых процедур она часто встречается и это нормальная практика. Я бы предложил usp_, а не sp_.