0

テーブルと関数を次のように定義できます。

CREATE TABLE mytable
(
  mycol integer
);

INSERT INTO mytable VALUES (1);

CREATE OR REPLACE FUNCTION myfunction (l_myvar integer) RETURNS mytable AS $$

DECLARE
l_myrow mytable;

BEGIN

SELECT      *
INTO        l_myrow
FROM        mytable
WHERE       mycol = l_myvar;

RETURN l_myrow;

END;
$$ LANGUAGE plpgsql;

この場合、l_myvar は、呼び出し時に渡される値のバインド変数として機能します。

SELECT * FROM myfunction(1);

mycol = 1 の行を返します

If I redefine the function as:

CREATE OR REPLACE FUNCTION myfunction (l_myvar integer) RETURNS mytable AS $$

DECLARE
l_myrow mytable;

BEGIN

SELECT      *
INTO        l_myrow
FROM        mytable
WHERE       mycol IN (l_myvar);

RETURN l_myrow;

END;
$$ LANGUAGE plpgsql;

SELECT * FROM myfunction(1);

mycol = 1 の行を返します

ただし、整数配列を渡して IN 句でこの配列を使用できるように関数定義を変更すると、エラーが発生します。

CREATE OR REPLACE FUNCTION myfunction (l_myvar integer[]) RETURNS mytable AS $$

DECLARE
l_myrow mytable;

BEGIN

SELECT      *
INTO        l_myrow
FROM        mytable
WHERE       mycol IN (array_to_string(l_myvar, ','));

RETURN l_myrow;

END;
$$ LANGUAGE plpgsql;

分析により、次のことが明らかになりました。

SELECT array_to_string(ARRAY[1, 2], ',');

期待どおり 1,2 を返します

SELECT * FROM myfunction(ARRAY[1, 2]);

エラーを返します

operator does not exist: integer = text

行で:

WHERE       mycol IN (array_to_string(l_myvar, ','));

私が実行した場合:

SELECT      *
FROM        mytable
WHERE       mycol IN (1,2);

期待どおりの結果が得られます。

示されているように、array_to_string(l_myvar, ',') が 1,2 に評価されるとすると、これらのステートメントが同等ではないのはなぜですか。

エラーメッセージから、それはデータ型と関係がありますが、IN(変数) 構造は = 変数構造とは異なる動作をしているように見えませんか?

ここでのルールは何ですか?

私がやりたいことを達成するために、すべてを文字列として扱い、EXECUTE へのステートメントを作成できることを知っているので、それを解決策として探しているわけではありません。この例で何が起こっているのかを理解したいと思います。このアプローチを機能させるための変更はありますか。特定の例は、値の配列を渡して、EXECUTE に頼らずに動的な IN 句を作成することですか?

前もって感謝します

クレイグ

4

1 に答える 1