web-dev-qa-db-ja.com

postgresの動的SQLクエリ

私は動的SQLを使用してpostgresでいくつかのクエリを実行しようとしました。

例:

EXECUTE format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition)))

Result_%s_tableの形式のテーブルをクエリする必要があります。ここでは、別のテーブルの正しいテーブル名(id)に置き換える必要があります。

エラーERROR: prepared statement "format" does not exist

リンク: クエリ結果postgresqlでの文字列置換

19
psteelk

EXECUTE ... USINGは、 PL/PgSQL でのみ機能します。つまり、関数内または DOブロック でPL/PgSQL言語で記述されています。プレーンSQLでは機能しません。プレーンSQLのEXECUTEは、準備されたステートメントを実行するために完全に異なります。 PostgreSQLのSQLダイアレクトで動的SQLを直接使用することはできません。

比較する:

my previous answer の2番目の最後のパーを参照してください。


PL/PgSQL以外で実行されていないことに加えて、SQLステートメントが間違っているだけでなく、期待どおりに動作しません。 (select id from ids where condition = some_condition)がsay 42を返す場合、idが整数の場合、ステートメントは失敗します。あなたが得るテキストにキャストされている場合:

EXECUTE format('SELECT * from result_%s_table', quote_ident('42'));
EXECUTE format('SELECT * from result_%s_table', '"42"');
EXECUTE 'SELECT * from result_"42"_table';

それは無効です。実際にresult_42_tableまたは"result_42_table"が必要です。次のようなものを書く必要があります。

EXECUTE format('SELECT * from %s', quote_ident('result_'||(select id from ids where condition = some_condition)||'_table'))

... quote_identを使用する必要がある場合。

28
Craig Ringer
CREATE OR REPLACE FUNCTION public.exec(
text)
RETURNS SETOF RECORD
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN 
    RETURN QUERY EXECUTE $1 ; 
END 
$BODY$;

使用法:

select * from exec('select now()') as t(dt timestamptz)
8
Inshua

使用してみてください

RETURN QUERY EXECUTE '<SQL Command>'

これにより、データが表形式に返されます。これをPostgreSQLのストアド関数に使用する必要があります。

PostgreSQLの動的クエリを使用したカスタムフィルターとカスタムソートの完全なデモンストレーションで作成済みです。次のURLにアクセスしてください: http://www.dbrnd.com/2015/05/postgresql-dynamic-sql/

4
Anvesh

EXECUTEはpl/pqsql環境でのみ動作します。

eXECUTEの代わりにSELECTで試してください

 SELECT format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition))

出力は動的クエリになります。

1
solaimuruganv

これらはすべて、OPの質問よりも複雑に見えます。別のフォーマットでこのトリックを行う必要があります..しかし、それは絶対に私が理解できない場合です。

OPの質問をどのように読んだかから、同様の状況にある他の人は、私がそれを手に入れた方法の恩恵を受けると思います。

RedshiftでPostgreを使用していますが、この問題にぶつかり、解決策を見つけました。

私は自分の日付を入れて、動的クエリを作成しようとしていました。

date = dt.date(2018, 10, 30)

query = ''' select * from table where date >= ''' + str(my_date) + ''' order by date '''

ただし、この方法で入力すると、クエリは条件を完全に無視します。

ただし、パーセント記号(%)を使用すると、日付を正しく挿入できます。

上記のステートメントを記述する正しい方法の1つは次のとおりです。

query = ''' select * from table where date >= ''' + ''' '%s' ''' % my_date + ''' order by date '''

したがって、これは役立つかもしれませんし、役に立たないかもしれません。私の状況で少なくとも一人が助けになることを願っています!

ご多幸を祈る。

1
spen.smith