标准化(主要是2NF和一些3NF表),我现在需要一个像下面这样的查询来爬上我的表结构来获取我需要的信息。 (PostgreSQL 9.3)
CREATE TEMPORARY TABLE test AS
With charts_on_date_of_service AS (
SELECT t.service_recid, t.tservice, t.chart_recid
FROM ( select s.recid as service_recid, s.tservice, p.chart_recid
from doctorservices d
join services s on (s.recid = d.service_recid)
join patients p on (p.recid = s.patient_recid)
where s.tservice::date = _tservice::date
) as t
)
select s.recid as service_recid, s.tservice, c.chart_recid, c.tservice as time_of_service
from charts_on_date_of_service c
join patients p on (p.chart_recid = c.chart_recid)
join services s on (s.patient_recid = p.recid)
join doctorservices d on ( d.service_recid = s.recid)
where s.tservice::date <= _tservice::date
order by c.chart_recid, s.tservice;
正如此查询所涉及的那样,我不想在plpgsql函数中复制它。也就是说,我想做类似的事情:
CREATE OR REPLACE FUNCTION test(_tservice timestamp)
RETURNS TABLE (service_recid bigint, chart_recid int, tservice timestamp, ct int) AS
$func$
DECLARE
CREATE TEMPORARY TABLE test AS .... <--THIS FAILS
cur CURSOR FOR
SELECT t.service_recid, t.tservice, t.chart_recid
FROM test t
BEGIN
... some processing commands on the temp table test and cursor cur....
END
我有几个相关的问题:
我似乎无法找到谷歌的答案。 非常感谢任何帮助或想法。
答案 0 :(得分:4)
你必须使用不同的方法。在PL / pgSQL中,任何CREATE
语句都不能在DECLARE
部分。它是任何其他声明,应该在功能体部分。如果您可以迭代动态创建的表,则必须使用unbound游标,并且必须在OPEN
语句中指定查询(或更好 - 使用FOR
周期):
CREATE OR REPLACE FUNCTION test(a int)
RETURNS TABLE (b int, c int, d int) AS $$
BEGIN
DROP TABLE IF EXISTS foo;
CREATE TEMP TABLE foo(col int);
INSERT INTO foo SELECT generate_series(1,a);
FOR b, c, d IN SELECT col, col + 1, col + 2 FROM foo
LOOP
RETURN NEXT;
END LOOP;
END; $$ LANGUAGE plpgsql;
此示例有效,但非常昂贵,只有在必要时才应使用 。临时表很昂贵,如果你不需要它,就不要使用它(有很好的理由:性能,复杂性,但通常没有必要)。 T-SQL
中的某些模式不会在Postgres中使用,有些工作需要不同的思考。您可以使用数组RETURN NEXT
,RETURN QUERY
语句:
CREATE OR REPLACE FUNCTION test(a int)
RETURNS table (b int, c int, d int) AS $$
BEGIN
RETURN QUERY SELECT col, col+1, col+2
FROM generate_series(1,a)
RETURN;
END; $$ LANGUAGE plpgsql;
对于类似的普通函数,最好使用SQL语言:
CREATE OR REPLACE FUNCTION test(a int)
RETURNS table (b int, c int, d int) AS $$
SELECT col, col+1, col+2
FROM generate_series(1,a)
$$ LANGUAGE sql;
你可以在Postgres中使用数组:
CREATE OR REPLACE FUNCTION test(a int)
RETURNS TABLE (b int, c int, d int) AS $$
DECLARE cols int[];
BEGIN
cols := ARRAY(SELECT generate_series(1,a));
RETURN QUERY
SELECT col, col + 1, col + 2
FROM unnest(cols) g(col);
RETURN;
END; $$ LANGUAGE plpgsql;