Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];

Вниз

Как заставить 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.042 c
1-1176922235
I-New
2007-04-18 22:50
2007.06.17
Создание ресурсов


3-1174975498
O.O
2007-03-27 10:04
2007.06.17
Выражение в Insert


15-1179579374
TCrash
2007-05-19 16:56
2007.06.17
С++ и перегружаемые функции


1-1176964731
kukuikar
2007-04-19 10:38
2007.06.17
Проверить существует ли сетевой путь или с сети ли сервер


5-1156153134
Darlock
2006-08-21 13:38
2007.06.17
Автоматическое создание HELPа для своего кода





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский