[英]plpgsql function: Return rows from a view created from random table
我想創建一個函數,該函數返回從未知表創建的視圖中的行:
CREATE OR REPLACE FUNCTION tt_query(text, timestamp without time zone)
RETURNS SETOF record AS
$$
DECLARE
orig_name ALIAS FOR $1;
data_tt ALIAS FOR $2;
BEGIN
[...]
EXECUTE 'create OR REPLACE TEMP view temp as
select *
from '
||orig_name
||' where trigger_changed >'
||quote_literal(data_tt)
||' ORDER BY trigger_changed DESC';
[...]--other work on view temp
--NOW I WANT RETURN THE ROW OF view temp
END;
$$
LANGUAGE plpgsql VOLATILE
好的,我想(有你的幫助)這個:
表:
create table t(a integer, b text);
功能:
CREATE OR REPLACE FUNCTION f()
RETURNS SETOF record AS
$$
BEGIN
RETURN QUERY EXECUTE 'SELECT * FROM t';
END;
$$
LANGUAGE plpgsql VOLATILE
類型:
CREATE TYPE y AS (
a int,
b text
);
現在可能嗎?:
select * from f() as y;
在我的情況下,y name是一個變量,我在另一個函數中創建它
它可以像這樣工作:
CREATE OR REPLACE FUNCTION tt_query(orig_name regclass, data_tt timestamp)
RETURNS SETOF record AS
$func$
BEGIN
EXECUTE 'CREATE OR REPLACE TEMP VIEW tmp as
select *
from '
|| orig_name
|| ' where trigger_changed >'
|| quote_literal(data_tt)
|| ' ORDER BY trigger_changed DESC';
-- other work on view tmp
-- return the rows of view temp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
注意使用對象標識符類型regclass
來自動避免SQL注入。
如果不需要,請不要使用過時的語法var ALIAS for $1
。 而是聲明參數名稱。
即使允許,我也不會使用關鍵字temp
作為標識符。 改用tmp
。
使用RETURN QUERY
返回一組記錄。 這甚至可以是沒有EXECUTE
的靜態調用。 但是,您將返回匿名記錄 ,Postgres要求每次調用都有一個列定義列表 :
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
這相當笨拙。
如果您知道返回類型(即使表名稱正在更改,列列表可能共享相同的類型),請在創建時聲明它。 考慮這個相關的問題:
PostgreSQL:錯誤:42601:返回“記錄”的函數需要列定義列表
如果返回類型隨提供的表名稱而變化 ,則仍有更好的解決方案。 由於您使用SELECT * FROM tbl
創建視圖,因此可以將表本身的已知類型用作多態參數:
CREATE OR REPLACE FUNCTION tt_query(orig_name anyelement, data_tt timestamp)
RETURNS SETOF anyelement AS
$func$
BEGIN
EXECUTE format('CREATE OR REPLACE TEMP VIEW tmp AS
SELECT * FROM %s
WHERE trigger_changed > %L
ORDER BY trigger_changed DESC'
,pg_typeof(orig_name)
,data_tt);
-- other work on view tmp
-- return the rows of view tmp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
簡化電話:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
還使用format()
進行安全和簡單的字符串連接。
這個相關答案的更多細節:
重構PL / pgSQL函數以返回各種SELECT查詢的輸出
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.