8

Firebird (FlameRobin を使用して実行) に大きなクエリがあり、あちこちでパラメーターを使用していますが、以下のクエリを実行するだけで済みます。

SELECT * FROM customers WHERE customerid = 1234;

1234を変数として定義したいcustomerIDので、簡単に別のものに置き換えることができます。

これを の中に入れる必要があることを学びましたEXECUTE BLOCK

EXECUTE BLOCK 
AS
DECLARE customerID INT = 1234;

BEGIN
  SELECT * FROM customers WHERE customerid = :customerID
END

重要な場合、私が得ているエラーはEngine Message : Dynamic SQL Error SQL error code = -104 Unexpected end of command - line 3, column 26

4

2 に答える 2

16

問題は、FlameRobin が、ステートメントがいつ終了し、次のステートメントが開始されるかを知る必要があることです。デフォルトでは、これにはセミコロン ( ;) が使用されます。ただし、EXECUTE BLOCKは基本的にデータベースに保存されないストアド プロシージャであるため、セミコロンをステートメント区切り文字として使用する PSQL コードも含まれています。

この結果、FlameRobin が不完全なステートメントをサーバーに送信しているため (つまり、;遭遇するたびにステートメントを送信しているため)、構文エラーが発生します。

を使用して別のステートメント ターミネータを使用するように FlameRobin に指示する必要がありますSET TERM。他の Firebird クエリ ツール (isql など) でもこれが必要ですが、実際には Firebird 自体の構文の一部ではありません!

したがって、コードを次のように実行する必要があります。

-- Instruct flamerobin to use # as the terminator
SET TERM #;
EXECUTE BLOCK 
AS
DECLARE customerID INT = 1234;

BEGIN
  SELECT * FROM customers WHERE customerid = :customerID;
END#
-- Restore terminator to ;
SET TERM ;#

ただし、このクエリは PSQL では無効であるため、これを行うとエラーが発生しますSELECT。PSQL ブロック内の A にはINTO、列を変数にマップする句が必要です。また、FlameRobin に返された から値を取得するには、次のドキュメントで説明されているように句EXECUTE BLOCKを指定する必要もあります。RETURNSEXECUTE BLOCK

-- Instruct flamerobin to use # as the terminator
SET TERM #;
EXECUTE BLOCK 
   RETURNS (col1 INTEGER, col2 VARCHAR(100))
AS
DECLARE customerID INT = 1234;

BEGIN
  SELECT col1, col2 FROM customers WHERE customerid = :customerID INTO :col1, :col2;
  SUSPEND;
END#
-- Restore terminator to ;
SET TERM ;#

私の知る限り、SUSPENDここでは技術的には必要ありませんが、含まれていない場合、Flamerobin は返された行をフェッチしません。

ただし、選択によって複数の行が生成される場合、上記は機能しません。そのためには、次FOR SELECT ... DOのものと組み合わせて使用​​する必要がありSUSPENDます。

-- Instruct flamerobin to use # as the terminator
SET TERM #;
EXECUTE BLOCK 
   RETURNS (col1 INTEGER, col2 VARCHAR(100))
AS
DECLARE customerID INT = 1234;

BEGIN
  FOR SELECT col1, col2 FROM customers WHERE customerid = :customerID INTO :col1, :col2
  DO
     SUSPEND;
END#
-- Restore terminator to ;
SET TERM ;#

here は行を返し、SUSPEND呼び出し元がその行をフェッチしてからFORループを続行するまで待機します。このようにして、結果を反復処理します。

IMHOは、パラメータ化に多大な労力を費やしています。FlameRobin を使用する場合は単純にパラメータ化しないことを検討するか、Firebird の通常のパラメータ プレースホルダのパラメータ値の要求をサポートするツールを使用することをお勧めします (ただし、正直なところ、存在するかどうかはわかりません)。

于 2013-10-10T15:36:51.803 に答える
1

入力値と戻り値が必要です。例:

EXECUTE BLOCK (p_customerID integer=?)
returns(col_1 type of column table.id_cv)
as
begin
  for
    select col_1 from table
    where customerID=:p_customerID
    into col_1 do
     suspend;
end

クライアント側としての Delphi:

myquery1.ParamByName('p_customerID ').Value:=1234;
myquery1.Open()
if not myquery1.IsEmpty then
begin
  // using returning values
  if myquery1.FieldbyName('col_1').AsString='this' then DoThat(); 
end;

入力パラメータや戻り値が必要な場合は、この方法を使用してください。

于 2021-08-16T13:30:42.873 に答える