2

Informixのストアド プロシージャに 1 つのパラメータで複数の値を渡す方法を教えてください。

これはよくある質問ですが、informix については何も言われていません。

投稿を見つけましたが、うまくいきません。DB のバージョンである必要がありますか、何か不足していますか?

私はこれを実行しようとしていますWHERE X IN (SELECT Y FROM TABLE(PARAM))

編集:

これは、私がやろうとしていることの例です。

CREATE PROCEDURE test_hector
(
    C LIST( SET (CHAR(10) NOT NULL ) NOT NULL)
)
RETURNING CHAR(10) AS C, CHAR(10) AS CVE, CHAR(50) AS DESC;

DEFINE vColumna like tclaves.columna;
DEFINE vClave like tclaves.clave;
DEFINE vdescve like tclaves.descve;

FOREACH
select columna, clave, descve
INTO vColumna, vClave,vdescve
from tclaves
where columna in (SELECT * FROM TABLE(C))
RETURN vColumna, vClave,vdescve WITH RESUME;
END FOREACH
END PROCEDURE;

実行しようとしていますが、シンタックスの問題があると思います

EXECUTE PROCEDURE test_hector( '{stspols,stsrepo}');

エラーメッセージが表示されます [Informix][Informix ODBC Driver][Informix]Invalid collection literal value.

この関数を実行execute function se_release()して、informix バージョンを取得しました。これが取得したものです。

column1
Spatial DataBlade Release 8.21.FC4R1 (Build 238)                 Compiled on Thu Aug 26 19:42:55 CDT 2010 with:                      IBM Informix Dynamic Server Version 10.00.FC7                    glslib-4.00.UC10

Aqua Data Studio 8.0.22プロシージャを作成して実行するために使用しています。実行中Windows 7 Ultimate 32-Bits

前もって感謝します。どんな助けでも

4

2 に答える 2

5

パラメータ タイプを適切なコレクション タイプとして定義します: LIST、SET、MULTISET (これは、相互参照された質問への回答で述べたものです)。

  • 何がうまくいかないのですか?
  • 何を試しましたか?
  • 表示されるエラー メッセージは何ですか?
  • どのバージョンの Informix サーバーを使用していますか?
  • ストアド プロシージャを作成するために、どのツールまたは API を使用していますか?
  • ストアド プロシージャを実行するためにどのツールまたは API を使用していますか?
  • どのプラットフォームで実行していますか?
  • どのように手順を呼び出していますか?

質問を拡大していただきありがとうございます。あなたは言う:

EXECUTE PROCEDURE test_hector('{stspols,stsrepo}');

エラーメッセージが表示されます[Informix][Informix ODBC Driver][Informix]Invalid collection literal value.

これは、見た目よりも簡単に修正できる問題かもしれません。プロシージャーの入力タイプはコレクション (実際には SET 値の LIST) であると想定されており、各値は文字ストリングです。次のように記述できます。

EXECUTE PROCEDURE test_hector(LIST{SET{'stspols','stsrepo'}});

この構文をテストするために、ダミーの手順を作成しました。

CREATE PROCEDURE test_hector(c LIST(SET (CHAR(10) NOT NULL ) NOT NULL))
    RETURNING CHAR(10) AS C, CHAR(10) AS CVE, CHAR(50) AS DESC;
    return "abc", "def", "ghi";
END PROCEDURE;

そして、それからの出力は期待どおりでした:

abc   def   ghi

{Informixでは、次の最初の で開始および終了するコメント スタイルがサポートされていることに注意してください}。ただし、その前のキーワードが SET、MULTISET、または LIST のいずれかである場合、そのコメント スタイルは抑制され{ます (もちろん、解析が非常に難しくなります!)。{}その意味を変えることなく、「上記の SQLのどこに を追加できますか」ということで、非常に (ひねくれていれば) 楽しむことができます。API が Informix{}コメントを認識しても、collection-exception を認識しない可能性があります。その場合、構文エラーが返される可能性があります (最初のコメントを開始コメント記号として}解釈すると、2 番目のエラーは予期されないため)。{その場合は、以下のいずれかの表記を使用してください。

コレクション (SET、MULTISET、LIST) リテラルの表記法は、時間の経過とともに進化しました。この代替表記法も機能します(最初に試したものとより密接に関連しており、最初に文書化されたものです):

EXECUTE PROCEDURE test_hector('LIST{SET{''stspols'',''stsrepo''}}');

SET 内の文字列は引用符で囲む必要がありますが、リテラル全体が文字列であるため、埋め込まれた引用符を二重にする必要があります。また、二重引用符と一重引用符を「ごまかして」使用することもできます。

EXECUTE PROCEDURE test_hector('LIST{SET{"stspols","stsrepo"}}');
EXECUTE PROCEDURE test_hector("LIST{SET{'stspols','stsrepo'}}");

以下の議論から、また別の回答で説明されているように、問題はネストされたコレクションに関連しているようです。ALIST{SET{"str1", "str2"}}は順序付けられたリスト (1 つのエントリを含む) です。そのエントリ自体は、特定の順序を持​​たない (個別の) 文字列のセットです。文字列を繰り返す必要がある場合は、MULTISET を使用します (ただし、順序は重要ではありません)。LIST を使用すると、順序が重要になります (リスト内での重複は許可されます)。

単純になるように、引数の型を選択するだけでよいように思えます。1 つのコレクション タイプを効果的に使用できる必要があります。リスト内で繰り返される文字列を処理する必要がないように、おそらく SET を指定しますが、MULTISET または LIST も有効なオプションです。プロシージャの名前を に変更test_3():

CREATE PROCEDURE test_3(c SET(CHAR(10) NOT NULL))
    RETURNING CHAR(10) AS r;
    DEFINE r CHAR(10);
    FOREACH SELECT * INTO r FROM TABLE(c)
        RETURN r WITH RESUME;
    END FOREACH;
END PROCEDURE;

次の両方のステートメントを実行でき、結果が表示されました。

+ EXECUTE PROCEDURE test_3(SET{'stspols','stsrepo'});
stspols
stsrepo
+ EXECUTE PROCEDURE test_3('SET{''stspols'',''stsrepo''}');
stspols
stsrepo

これは ESQL/C インターフェースを使用していました。秒を ODBC で使用できるようにする必要があります。最初のものは -201 構文エラーを引き起こす可能性があります。

SET よりも LIST を使用する場合は、上記のコードで SET を LIST に変更します。

+ CREATE PROCEDURE test_3(c LIST(CHAR(10) NOT NULL))
    RETURNING CHAR(10) AS r;
    DEFINE r CHAR(10);
    FOREACH SELECT * INTO r FROM TABLE(c)
        RETURN r WITH RESUME;
    END FOREACH;
END PROCEDURE;
+ EXECUTE PROCEDURE test_3(LIST{'stspols','stsrepo'});
stspols
stsrepo
+ EXECUTE PROCEDURE test_3('LIST{''stspols'',''stsrepo''}');
stspols
stsrepo
于 2012-06-05T13:15:27.577 に答える
1

別の方法で試してみたところ、解決策が見つかりました。

Listパラメータをではなくとして受け入れるように手順を変更しましたList{SET...

CREATE PROCEDURE test_hector
(
    C LIST( CHAR(10) NOT NULL )
)
RETURNING CHAR(10) AS C, CHAR(10) AS CVE, CHAR(50) AS DESC;

DEFINE vColumna like tclaves.columna;
DEFINE vClave like tclaves.clave;
DEFINE vdescve like tclaves.descve;

FOREACH
select columna, clave, descve
INTO vColumna, vClave,vdescve
from tclaves
where columna in (SELECT * FROM TABLE(C))
RETURN vColumna, vClave,vdescve WITH RESUME;
END FOREACH
END PROCEDURE;

そして、このように実行します。

EXECUTE PROCEDURE test_hector('LIST{''stspols'',''stsrepo''}');

またはこのように

EXECUTE PROCEDURE test_hector3('LIST{"stspols","stsrepo"}');

そして、それは魅力のように機能しました。

于 2012-06-13T18:42:18.710 に答える