SQL Server / Delphi: как передать список целых чисел в качестве параметра, используя тип табличной переменной? - PullRequest
0 голосов
/ 27 апреля 2018

Я использую 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 Ответ

0 голосов
/ 27 апреля 2018

То, что вам нужно, - это передать массив (это поможет с запросом 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_.

...