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_.

Другие вопросы по тегам