动态查询创建和执行 PostgreSQL
Dynamic Query Creation and Execution PostgreSQL
下面有两个表和两个 pl/pgsql
函数。
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
函数 returns 查询 string。
我如何修改 "use_generated_string" 函数,以便我可以通过调用 use_generated_string
函数获得以下查询的结果。
SELECT * FROM tt1 UNION ALL SELECT * FROM tt2;
有人能帮忙吗?
使用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)
如果您声明 return 类型(并将被调用的 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;
如果 return 类型应该保持动态,这是一个微妙的问题,我建议从阅读 Erwin Brandstetter's excellent answers.
开始
klin 的回答通过使用 RAISE NOTICE
避免了整个问题,这是非常聪明的,但我不确定人们将如何使用这样一个调用的结果,除了手动文本解析。
下面有两个表和两个 pl/pgsql
函数。
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
函数 returns 查询 string。
我如何修改 "use_generated_string" 函数,以便我可以通过调用 use_generated_string
函数获得以下查询的结果。
SELECT * FROM tt1 UNION ALL SELECT * FROM tt2;
有人能帮忙吗?
使用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)
如果您声明 return 类型(并将被调用的 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;
如果 return 类型应该保持动态,这是一个微妙的问题,我建议从阅读 Erwin Brandstetter's excellent answers.
开始klin 的回答通过使用 RAISE NOTICE
避免了整个问题,这是非常聪明的,但我不确定人们将如何使用这样一个调用的结果,除了手动文本解析。