2012-10-08 154 views
13

我正在嘗試使用動態SQL在postgres中運行一些查詢。postgres中的動態sql查詢

實施例:

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

鏈接:string substitution with query result postgresql

回答

21

EXECUTE ... USING只能在PL/PgSQL - 即寫在PL/pgSQL的語言功能或DO blocks內。它在純SQL中不起作用;普通SQL中的EXECUTE完全不同,用於執行預準備語句。您不能直接在PostgreSQL的SQL方言中使用動態SQL。

比較:

見第2最後面值my prior answer


除不除在運行PL/pgSQL的SQL語句是錯誤的,它不會做你期望的。如果(select id from ids where condition = some_condition)返回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

+1

只是補充,一個'DO'塊總是返回void,並且不接受任何參數,所以我覺得OP被限制的功能。 –

+1

@Clodoaldo好點 - 他們可以執行'SELECT',但除非他們像SELECT ... INTO'這樣的臨時表執行一些真正的迂迴操作,否則它們不會做任何好事。 –

+1

@CraigRinger你好,我知道我晚了一點晚,但你可以建議在PostgreSQL的動態SQL的任何好的教程?我找不到任何。我想創建一個全功能的動態查詢。檢查[this](https://stackoverflow.com/questions/48216935/pl-pgsql-for-all-in-one-dynamic-query)問題,如果你想。謝謝 – slevin

1

EXECUTE只能在pl/pqsql環境下工作。

,而不是執行與SELECT

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

輸出嘗試將動態查詢。

+0

動態查詢的文本當然可以,但它不會執行查詢。查看之前的鏈接帖子。 –

+0

是的,我已經通過了詳細的動態qry執行,這裏只是我提到的是EXECUTE將只在pl/pqsql環境中工作,並且當我發佈我的答案時,我真的沒有注意到你的迴應。 – solaimuruganv

+0

不用擔心。它只是不回答這個問題,即如何執行動態SQL。 –

3

使用

RETURN QUERY EXECUTE '<SQL Command>' 

這將數據返回到表的形式嘗試。你必須使用它來存儲PostgreSQL的函數。

我已經創建了使用PostgreSQL動態查詢的自定義過濾器和自定義排序的完整演示。 請訪問此網址: http://www.dbrnd.com/2015/05/postgresql-dynamic-sql/

0
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)