Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.06.17;
Скачать: CL | DM;

Вниз

Как заставить fibs понимать внутренние и внешние параметры Execut   Найти похожие ветки 

 
DelphiLexx ©   (2007-03-26 12:22) [0]

Как заставить FIBS или FIBPlus понимать внутренние и внешние параметры ExecuteBlock"a.
т.е., например есть запрос типа:

EXECUTE BLOCK (X INTEGER = :X)
RETURNS (Y VARCHAR)
AS
DECLARE V INTEGER;
BEGIN
INSERT INTO T(...) VALUES (... :X ...);
SELECT ... FROM T INTO :Y;
SUSPEND;
END
[/SRC]
Чтобы заставить FIBDataSet понимать парамерт :Y - необходимо сдедать
FIBDataSet.ParamsCheck := False, но в этом случае не распознается параметр :X. Как сделать так, чтобы понимался и параметр :X и параметр :Y


 
atruhin ©   (2007-03-26 16:01) [1]

А какого лешего FibPlus должен что то знать о внутренних параметрах?
Сделай: EXECUTE BLOCK (X INTEGER = :X, Y INTEGER = :Y)


 
Val ©   (2007-03-26 17:33) [2]

Y - это внутренний параметр?


 
Johnmen ©   (2007-03-26 17:43) [3]

Что за компонент, который позволяет указывать выполнение блока?


 
PEAKTOP ©   (2007-03-26 20:56) [4]

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

($firebird/doc/sql.extensions/README.execute_block.txt)

....................
The client should preprocess only head of the SQL statement or use "?"
instead of ":" as parameter indicator because in a body of the block may be links
to local variables and \ or parameters with a colon ahead.
...........................
(c) Vlad Horsun <horsun@kdb.dp.ua>

Не знаю, где это в FIBPlus зашито, но в InterBaseExpress я решал следующим образом:
1) Создал класс, потомок от TParams с методом  ParseSQL_FB2

UNIT
 IBXClasses;
INTERFACE
USES
  Classes
 ,DB
 ,FMTBcd
 ,SqlTimSt;
TYPE
 TIBXParams = class(TParams)
 public
   function ParseSQL_FB2(SQL: String; DoCreate: Boolean): String; virtual;
 end;

IMPLEMENTATION
uses
 SysUtils;

function TIBXParams.ParseSQL_FB2(SQL: String; DoCreate: Boolean): String;
const
 Literals = ["""", """, "`"];
var
 Value, CurPos, StartPos: PChar;
 CurChar: Char;
 Literal: Boolean;
 EmbeddedLiteral: Boolean;
 Name: string;

 function NameDelimiter: Boolean;
 begin
   Result := CurChar in [" ", ",", ";", ")", #13, #10];
 end;

 function IsLiteral: Boolean;
 begin
   Result := CurChar in Literals;
 end;

 function StripLiterals(Buffer: PChar): string;
 var
   Len: Word;
   TempBuf: PChar;

   procedure StripChar;
   begin
     if TempBuf^ in Literals then
       StrMove(TempBuf, TempBuf + 1, Len - 1);
     if TempBuf[StrLen(TempBuf) - 1] in Literals then
       TempBuf[StrLen(TempBuf) - 1] := #0;
   end;

 begin
   Len := StrLen(Buffer) + 1;
   TempBuf := AllocMem(Len);
   try
     StrCopy(TempBuf, Buffer);
     StripChar;
     Result := StrPas(TempBuf);
   finally
     FreeMem(TempBuf, Len);
   end;
 end;

begin
 Result := SQL;
 Value := PChar(Result);
 if DoCreate then Clear;
 CurPos := Value;
 Literal := False;
 EmbeddedLiteral := False;
 repeat
   while (CurPos^ in LeadBytes) do Inc(CurPos, 2);
   CurChar := CurPos^;
   if (CurChar = "?") and not Literal and ((CurPos + 1)^ <> "?") then
   begin
     StartPos := CurPos;
     while (CurChar <> #0) and (Literal or not NameDelimiter) do
     begin
       Inc(CurPos);
       while (CurPos^ in LeadBytes) do Inc(CurPos, 2);
       CurChar := CurPos^;
       if IsLiteral then
       begin
         Literal := Literal xor True;
         if CurPos = StartPos + 1 then EmbeddedLiteral := True;
       end;
     end;
     CurPos^ := #0;
     if EmbeddedLiteral then
     begin
       Name := StripLiterals(StartPos + 1);
       EmbeddedLiteral := False;
     end
     else Name := StrPas(StartPos + 1);
     if DoCreate then
       TParam(Add).Name := Name;
     CurPos^ := CurChar;
     StartPos^ := "?";
     Inc(StartPos);
     StrMove(StartPos, CurPos, StrLen(CurPos) + 1);
     CurPos := StartPos;
   end
   else if (CurChar = "?") and not Literal and ((CurPos + 1)^ = "?") then
     StrMove(CurPos, CurPos + 1, StrLen(CurPos) + 1)
   else if IsLiteral then Literal := Literal xor True;
   Inc(CurPos);
 until CurChar = #0;
end;

END.


 
PEAKTOP ©   (2007-03-26 21:17) [5]

Как видно из примера, метод не парсит "двоеточие", а только вопросительный знак.
2) создал модуль IBQueryEx.pas, скопировав файл в проводнике, содержащий класс IBQueryEx, в котором перекрыл стандартные Params и метод QueryChanged.

UNIT
 IBQueryEx;
INTERFACE
USES
...............
IBXClasses
.............;
TYPE
 TIBQueryEx = class(TIBCustomDataSet)
 private
   FSQL                :TStrings;
   FPrepared           :Boolean;
   FParams             :TParams;
   FText               :string;
   FRowsAffected       :Integer;
   FCheckRowsAffected  :Boolean;
   FGenerateParamNames :Boolean;
   function  GetRowsAffected: Integer;
   procedure PrepareSQL(Value: PChar);
   procedure QueryChanged(Sender: TObject);
   procedure ReadParamData(Reader: TReader);
   procedure SetQuery(Value: TStrings);
   procedure SetParamsList(Value: TParams);
   procedure SetParams;
   procedure SetParamsFromCursor;
   procedure SetPrepared(Value: Boolean);
   procedure SetPrepare(Value: Boolean);
   procedure WriteParamData(Writer: TWriter);
   function  GetStmtHandle: TISC_STMT_HANDLE;
 protected
   { IProviderSupport }
   procedure PSExecute;                                   override;
   function  PSGetParams   :TParams;                      override;
   function  PSGetTableName:string;                       override;
   procedure PSSetCommandText(const CommandText: string); override;
   procedure PSSetParams(AParams: TParams);               override;
   {overriding TDataSet methods}
   procedure DefineProperties(Filer: TFiler);             override;
   procedure InitFieldDefs;                               override;
   procedure InternalOpen;                                override;
   procedure Disconnect;                                               override;
   function  GetParamsCount            :Word;
   function  GenerateQueryForLiveUpdate:Boolean;
   procedure SetFiltered(Value: Boolean);                              override;
 public
   constructor Create(AOwner: TComponent);                             override;
   destructor  Destroy;                                                override;
   procedure   BatchInput(InputObject: TxFBBatchInput);
   procedure   BatchOutput(OutputObject: TxFBBatchOutput);
   procedure   ExecSQL;
   procedure   GetDetailLinkFields(MasterFields, DetailFields: TList); override;
   function    ParamByName(const Value: string): TParam;
   procedure   Prepare;
   procedure   UnPrepare;
   property    LiveMode;
   property    Prepared: Boolean read FPrepared write SetPrepare;
   property    ParamCount: Word read GetParamsCount;
   property    StmtHandle: TISC_STMT_HANDLE read GetStmtHandle;
   property    StatementType;
   property    Text: string read FText;
   property    RowsAffected: Integer read GetRowsAffected;
   property    GenerateParamNames: Boolean read FGenerateParamNames write FGenerateParamNames;
 published
   property Active;
   property BufferChunks;
   property CachedUpdates;
   property DataSource read GetDataSource write SetDataSource;
   property Constraints stored ConstraintsStored;
   property ParamCheck;
   property SQL: TStrings read FSQL write SetQuery;
   property Params: TParams read FParams write SetParamsList stored False;
   property UniDirectional default False;
   property UpdateObject;
   property Filtered;
   property GeneratorField;
   property BeforeDatabaseDisconnect;
   property AfterDatabaseDisconnect;
   property DatabaseFree;
   property BeforeTransactionEnd;
   property AfterTransactionEnd;
   property TransactionFree;
   property OnFilterRecord;
 end;

IMPLEMENTATION
//==============================================================================
constructor TIBQueryEx.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FSQL                      := TStringList.Create;
 TStringList(SQL).OnChange := QueryChanged;
 FParams                   := TIBXParams.Create(Self);
 ParamCheck                := True;
 FGenerateParamNames       := False;
 FRowsAffected             := -1;
end;
//==============================================================================
procedure TIBQueryEx.QueryChanged(Sender: TObject);
var
 List: TParams;
begin
 if not (csReading in ComponentState) then
   begin
   Disconnect;
   if ParamCheck or (csDesigning in ComponentState) then
     begin
     List := TIBXParams.Create(Self);
     try
       FText := TIBXParams(List).ParseSQL_FB2(SQL.Text, True);
       List.AssignValues(FParams);
       FParams.Clear;
       FParams.Assign(List);
      finally
       List.Free;
      end;
     end
    else
     FText := SQL.Text;
   DataEvent(dePropertyChange, 0);
   end
  else
   FText := FParams.ParseSQL(SQL.Text, False);
 SelectSQL.Assign(SQL);
end;
//==============================================================================

................

END.



 
atruhin ©   (2007-03-27 18:59) [6]

Нда, в посте > [1] atruhin ©   (26.03.07 16:01) ошибся, не правильно вопрос прочитал.
Автору: какая версия FIB+ ? Нормальную поддержку EXECUTE BLOCK ввели не так давно.


 
DelphiLexx ©   (2007-03-28 09:14) [7]


> Автору: какая версия FIB+ ? Нормальную поддержку EXECUTE
> BLOCK ввели не так давно.

Версия в исходниках не указана.
Вот здесь можешь взять:
http://up.spbland.ru/files/07032839/


 
Виталий Панасенко ©   (2007-03-28 10:22) [8]

Все намного проще - при создании скриптов можно указать, какой символ использовать в качестве обозначения параметров - ":" или "?". Правда, сам генератор чего-то все равно ставит ":". Но можно руками подправить


 
DelphiLexx ©   (2007-03-28 18:27) [9]

> Правда, сам генератор чего-то все равно ставит ":". Но можно
> руками подправить

Где именно нужно подправить


 
atruhin ©   (2007-03-28 18:53) [10]

> Вот здесь можешь взять:
> http://up.spbland.ru/files/07032839/

И на хх я буду по помойкам FIB собирать. Учитывая их стоимость.



Страницы: 1 вся ветка

Текущий архив: 2007.06.17;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.025 c
15-1179454304
Slider007
2007-05-18 06:11
2007.06.17
С днем рождения ! 18 мая


3-1175056612
Xmen
2007-03-28 08:36
2007.06.17
Вставка даты в базу


15-1179865500
antonn
2007-05-23 00:25
2007.06.17
логин юзера на сайт (общий вопрос по безопасности)


2-1180100114
забыл ник %)
2007-05-25 17:35
2007.06.17
Подсказка в трее


15-1179779275
ElectriC
2007-05-22 00:27
2007.06.17
Закачка файлов