Форум: "Базы";
Текущий архив: 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.065 c