TADOStoredProc
От: vrtlpilot  
Дата: 21.05.14 14:33
Оценка:
Добрый день, уважаемые.

В приложении повсеместно используется TADOStoredProc. Причем для вызова процедур и передачи параметров используется некий анализатор строки.

Было принято соглашение (системе уже много лет), что у ХП
первый параметр — это результат выполнения varchar(250)
второй параметр — это ID элемента в наборе данных int
затем динамически добавляются различные параметры, которые переданы в строке с разделителями в анализатор.

Проблема возникла в попытке оптимизации. Для вызове процедуры на SQL Server 2008 используется примерно следующий алгоритм:

 With _Form_.ADO_Stp do begin
   ConnectionString := ConStr;
   if (MainCFG['TimeOutPeriod'] <> '') and IsNumber_Str(MainCFG['TimeOutPeriod']) then CommandTimeOut := StrToInt(MainCFG['TimeOutPeriod']);
   ProcedureName:=Name_Proc;

   Parameters.AddParameter;
   Parameters[0].DataType:=ftInteger;
   Parameters[0].Direction:=pdReturnValue;
   Parameters[0].Value:=0;

   Parameters.AddParameter;
   Parameters[1].DataType:=ftInteger;
   Parameters[1].Direction:=pdInput;
   Parameters[1].Value:=0;

   if PStr<>'' then begin
     TS_Par := TStringList.Create;
     StrToTStr(PStr, ADelim, TS_Par);
     for i := 0 to TS_Par.Count-1 do begin
      Parameters.AddParameter;
      if Pos('''',TS_Par[i])<>0 then begin
         Parameters[i+2].DataType:=ftString;
         Parameters[i+2].Direction:=pdInput;
         Parameters[i+2].Value:=Copy(TS_Par[i],2,length(TS_Par[i])-2);
         end
        else begin
         Parameters[i+2].DataType:=ftInteger;
         Parameters[i+2].Direction:=pdInput;
         if TS_Par[i]='' then TS_Par[i]:='0';
           Parameters[i+2].Value:=StrToInt(TS_Par[i]);

      end
     end;

//.............
//затем идет цикл по выбранным записям с заполнением списка ID
//.............
//затем в цикле идет вызов
 _Form_.ADO_StP.ExecProc;


ХП описывается на сервере как:


CREATE PROCEDURE [dbo].[usp_Dogovor_ADDHis]
    @Result varchar(250) OUTPUT, 
    @IDDog int, 
    @Otval_Etap varchar(10),
    @KodOtval_Type int = NULL,
    @KodOtval_Ini int = NULL,
    @Otval_Prim varchar(250) = NULL,
    @ContrDate varchar(10)


Если посмотреть в QA, то вызов из приложения выглядит так

exec usp_Dogovor_AddHis 4591,'20140301',23,2,'','20140521'

нулевой параметр (как мне кажется) не передается, из-за этого сервер выдает ошибку:
Operand type clash: varchar is incompatible with int

Если честно, то непосредственно со TADOStoredProc я работаю впервые, раньше делал через TADOCommand.
Объясните, пожалуйста, в чем грабли.
Re: TADOStoredProc
От: 1303  
Дата: 22.05.14 01:03
Оценка: 3 (1)
Здравствуйте, vrtlpilot, Вы писали:

...
V> Parameters.AddParameter;
V> Parameters[0].DataType:=ftInteger;
V> Parameters[0].Direction:=pdReturnValue;
V> Parameters[0].Value:=0;

V>Если посмотреть в QA, то вызов из приложения выглядит так

V>exec usp_Dogovor_AddHis 4591,'20140301',23,2,'','20140521'

Как видишь, первый параметр в SQL не попадает. Потому что pdReturnValue — это тип, используемый для получения значения функции, ежели я не путаю (давно уже не работал с ADO компонентами), а не out параметра. Попробуй использовать pdOutput.
Re[2]: TADOStoredProc
От: vrtlpilot  
Дата: 22.05.14 05:53
Оценка:
Здравствуйте, 1303, Вы писали:

V>> Parameters[0].Direction:=pdReturnValue;

V>> Parameters[0].Value:=0;

V>>exec usp_Dogovor_AddHis 4591,'20140301',23,2,'','20140521'


1>Как видишь, первый параметр в SQL не попадает. Потому что pdReturnValue — это тип, используемый для получения значения функции, ежели я не путаю (давно уже не работал с ADO компонентами), а не out параметра. Попробуй использовать pdOutput.


Спасибо. Странно, что я сам до этого не догадался. Теперь остается только перетестить весь остальной проект после рефакторинга. Но это уже совсем другая история.

Тема закрыта.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.