2012-05-17 15 views
11

クエリを実行し、テーブル名とカラム名が関数に与えられた特権である結果を返す関数を作成する必要があります。とき実行Postgres動的クエリ関数

これは私にエラー与え
CREATE OR REPLACE FUNCTION qa_scf(tname character varying, cname character varying) 
RETURNS SETOF INT AS 
$BODY$ 
BEGIN 
RETURN QUERY SELECT * FROM tname WHERE cname !='AK' AND cname!='CK'; 
END; 
$BODY$ 
LANGUAGE plpgsql VOLATILE 
COST 100 
ROWS 1000; 

「関係 『をTNAME』デは存在しない」:私は現在、これは持っています。私はPostgres用の関数を作成するために新しく、どんな助けもありがとうございます。私は戻り値intが間違っているように感じますが、返される行のすべての列を返すようにするために何を置くべきかわかりません。ありがとう!

答えて

17

このような識別子の代わりに変数を使用することはできません。動的クエリーでそれを行う必要があります。あなたは、PostgreSQL 9.1を使用している場合

EXECUTE 'SELECT * FROM ' || quote_ident(tname) 
     || ' WHERE ' || quote_ident(cname) || ' NOT IN (''AK'',''CK'');' 
INTO result_var; 

以上、あなたがはるかに簡単にこの文字列を構築しますthe format() functionを使用することができます。それは次のようになります。

+0

result_varをどのように宣言すればよいですか? –

+1

適切なquote_FOO()関数を使用せずに動的SQL文に値を挿入したり、ドア・イン・インジェクション攻撃を開かないでください。 – dbenhur

+0

これは内部向きのデータベースです。 –

13

ダイナミックステートメントとして実行する文字列を動的に構築することなく、テーブル名とカラム名をパラメータまたは変数として指定することはできません。 Postgresには、executing dynamic statementsについての優れた入門書があります。 quote_ident()またはquote_literal()を使用して、識別子とリテラルを正しく引用することが重要です。 format()関数は、動的SQL文の作成をクリーンアップするのに役立ちます。 SETOF INTEGERを返す関数を宣言したので、*ではなく、整数フィールドを選択する必要があります。

CREATE OR REPLACE FUNCTION qa_scf(tname text, cname text) 
RETURNS SETOF INTEGER AS 
$BODY$ 
BEGIN 
    RETURN QUERY EXECUTE format(
    'SELECT the_integer_field FROM %I WHERE %I NOT IN (%L, %L)', 
            tname, cname, 'AK', 'CK' 
); 
END; 
$BODY$ 
LANGUAGE plpgsql; 
+0

すべての列を返すようにするにはどうすればよいですか? –

+0

'SELECT *'と 'RETURNS SETOF RECORD'を宣言できます。次に、消費者は記録タプルを理解しなければならない。 http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions – dbenhur

+0

そして、列定義リストにはどのようにしたらいいですか?これを動的にプルする方法はありますか? –