複数行のすべてのフィールド値を連結するためのFirebirdストアドプロシージャ

StackOverflow https://stackoverflow.com/questions/183675

質問

私の目標は、複数の行からすべてのフィールド値を1つの単一の出力変数(varchar(some_length)など)に収集できるストアドプロシージャを作成することです。それは奇妙な解決策に思えるかもしれませんが、私はその状況で使用できる唯一のものであると確信しています。 私のFirebirdは1.5および方言3です(意味はわかりません)。 だから誰かがアルゴリズムの例を手伝ってくれるかもしれない。

役に立ちましたか?

解決

次の手順は、説明した内容を実行します。

SET TERM !!;
CREATE PROCEDURE concat_names
  RETURNS (concat VARCHAR(2000))
AS
DECLARE VARIABLE name VARCHAR(100);
BEGIN
  concat = '';
  FOR SELECT first_name || ' ' || last_name FROM employee INTO :name
  DO BEGIN
    concat = concat || name || ', ';
  END
END!!
SET TERM ;!!
EXECUTE PROCEDURE concat_names;

しかし、私はこの解決策の知恵に疑問を呈しています。目的のデータセットのすべての行に対してVARCHARが十分に長いことをどのように確認しますか?

クエリを実行して、結果を行ごとにアプリケーションに返す方がはるかに簡単で安全です。すべてのアプリケーションプログラミング言語には、文字列を連結するメソッドがありますが、さらに重要なことは、データの増加を管理するためのより柔軟なメソッドがあることです。

ところで、「方言」 FirebirdおよびInterBaseで、InterBase 5.x用に開発されたアプリケーションがInterBaseおよびFirebirdの新しいバージョンで動作できるように導入された互換モードを指します。それはほぼ10年前のことで、今日では、方言3よりも低いものを使用する必要はありません。

他のヒント

連結するときはnull値をテストする必要があります。2つのフィールドとそれらの間のセパレータの例を次に示します。

    CREATE PROCEDURE CONCAT(
    F1 VARCHAR(385),
    F2 VARCHAR(385),
    SEPARATOR VARCHAR(10))
RETURNS (
    RESULT VARCHAR(780))
AS
begin

  if ((:f1 is not null) and (:f1 <> '')) then
    result = :f1;

  if ((:f2 is not null) and (:f2 <> '')) then
    if ((result is not null) and (result <> '')) then
      begin
        if ((:separator is not null) and (separator <> '')) then
          result = result||separator||f2;
        else
          result = result||f2;
      end
    else
      result = f2;

  suspend;
end

Firebirdストアドプロシージャを使用して複数の行を返すのは非常に簡単です。

使用しないでください:

execute procedure proc_name(value);

代わりに次を使用します:

select * from proc_name(value);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top