2015-10-27 116 views
2

我有两个以下的表和两个pl/pgsql函数。动态查询创建和执行PostgreSQL

CREATE TABLE tt1(id int, name text); 
CREATE TABLE tt2(id int, name text); 

INSERT INTO tt1 VALUES (1,'name1'); 
INSERT INTO tt1 VALUES (2,'name2'); 
INSERT INTO tt1 VALUES (3,'name3'); 
INSERT INTO tt2 VALUES (4,'name4'); 
INSERT INTO tt2 VALUES (5,'name5'); 
INSERT INTO tt2 VALUES (6,'name6'); 


CREATE OR REPLACE FUNCTION query_string() RETURNS TEXT AS 
$BODY$ 
DECLARE 
query1 TEXT:=''; 
BEGIN 
    query1 := 'SELECT * FROM tt1 UNION ALL SELECT * FROM tt2';  
    RETURN query1; 
END; 
$BODY$ 
LANGUAGE PLPGSQL; 



CREATE OR REPLACE FUNCTION use_generated_string() RETURNS VOID  AS 
$BODY$ 
DECLARE 
BEGIN 
     -- Need to modify here to get the result same as below query by 
     -- calling above function. 
     -- "SELECT * FROM tt1 UNION ALL SELECT * FROM tt2" 
END; 
$BODY$ 
LANGUAGE PLPGSQL; 

query_string函数返回的查询字符串。 如何修改“use_generated_string”函数,以便通过调用use_generated_string函数来获得以下查询的结果。

SELECT * FROM tt1 UNION ALL SELECT * FROM tt2; 

任何人都可以帮忙吗?

回答

1

使用EXECUTE

CREATE OR REPLACE FUNCTION use_generated_string() RETURNS VOID  AS 
$BODY$ 
DECLARE 
    rec record; 
BEGIN 
    FOR rec IN EXECUTE(query_string()) LOOP 
     RAISE NOTICE '%', rec.name; 
    END LOOP; 
END; 
$BODY$ 
LANGUAGE PLPGSQL; 

SELECT use_generated_string(); 

NOTICE: name1 
NOTICE: name2 
NOTICE: name3 
NOTICE: name4 
NOTICE: name5 
NOTICE: name6 
use_generated_string 
---------------------- 

(1 row) 
2

如果声明的返回类型(并保持固定到该类型叫做SQL),你可以这样做:

CREATE OR REPLACE FUNCTION use_generated_string() RETURNS TABLE(c1 INT, c2 TEXT) AS 
$BODY$ 
DECLARE 
BEGIN 
    RETURN QUERY EXECUTE query_string(); 
END; 
$BODY$ 
LANGUAGE PLPGSQL; 

如果返回类型应该保持活力,这是一个棘手的问题,我建议先阅读Erwin Brandstetterexcellentanswers

klin的答案用RAISE NOTICE,这是相当聪明的避免了整个问题,但我不能确定一个将如何去使用这样的调用的结果,除了手动文本解析。