テーブルと関数を次のように定義できます。
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 句を作成することですか?
前もって感謝します
クレイグ