postgresql 在PL/pgSQL块中运行SELECT

qojgxg4l  于 11个月前  发布在  PostgreSQL
关注(0)|答案(5)|浏览(172)

我是PostgreSQL的新手,我必须在SSRS报告中使用内联查询来从PostgreSQL DB中获取数据。
场景是:基于所选的报表参数值,我需要从不同的表中获取输出。请参见下面的内联查询示例。

DO
    $do$

    BEGIN
    IF ($1 = 'Monthly') THEN

    SELECT *
    FROM table1;

    ELSE 

    SELECT *
    FROM table2;

    END IF;

    END
    $do$

字符串
上述查询给出错误,

错误:查询没有结果数据的目标SQL状态:42601提示:如果你想放弃一个SELECT的结果,使用PERFORM代替。上下文:PL/pgSQL函数inline_code_block line 6 at SQL语句

请注意,我不能使用存储过程或函数来检索所需的数据,我只能使用内联查询。
谁能告诉我如何解决上述错误?

dvtswwa3

dvtswwa31#

您的示例有两个问题- DO语句(匿名块)不支持
1.参数
1.正在返回结果。
PostgreSQL不支持在T-SQL或MS-SQL中使用的称为未绑定查询的技术。每个查询都必须有指定的目标。您可以使用函数来代替(table1table2应该具有相同的结构):

CREATE OR REPLACE FUNCTION foo(frequency)
RETURNS SETOF table1 AS $$
BEGIN
  IF $1 = 'Monthly' THEN
    RETURN QUERY SELECT * FROM table1;
  ELSE
    RETURN QUERY SELECT * FROM table2;
  END IF;
  RETURN;
END;
$$ LANGUAGE plpgsql;

SELECT * FROM foo('Monthly');

字符串

rqqzpn5f

rqqzpn5f2#

假设这些表具有相同的列结构,您可以使用联合来在单个查询中执行这两个选项。

SELECT * FROM table1 WHERE $1 = 'Monthly'
UNION ALL
SELECT * FROM table2 WHERE NOT ($1 = 'Monthly')

字符串

5f0d552i

5f0d552i3#

您可以创建一个临时表来获取外部结果,但不传递参数:

DO
$$
BEGIN
IF <> THEN
CREATE TEMPORARY TABLE foo AS
SELECT *FROM ...
 ELSE

 ....
 END IF;
 END
 $$
 SELECT * FROM FOO;

字符串

qhhrdooz

qhhrdooz4#

如果你创建了一个函数,它接受一个'select'查询文本并返回SETOF RECORD,那么你可以直接在SQL窗口中执行:

with c_sql as (
-- >>> --- your any query
select STRING_AGG('select ''"' || t.table_schema || '"."' || t.table_name || '"'' tab, count(*) cnt from "' || t.table_schema || '"."' || t.table_name || '"', ' union all ')
|| ' order by 2 desc' v_sql
from information_schema.tables t
where t.table_schema like 'tiger'
-- <<< ---
)
select ex.* from c_sql
LEFT JOIN lateral ( select * from execsql(c_sql.v_sql) as ss(tab text, cnt int8) ) ex on true

字符串
下面是execsql函数:

CREATE OR REPLACE FUNCTION public.execsql(
text)
RETURNS SETOF RECORD
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN 
    RETURN QUERY EXECUTE $1 ; 
END 
$BODY$;


注意,你应该将execsql函数的结果转换为与你的'select'查询匹配的特定记录结构。
附言:* 顺便说一下,我不明白为什么没有人推荐这样一种简单的方法来执行几乎任何请求。这是一种非常有用的方法,可以快速形成查询并执行它,而不会创建阻塞数据库的单独函数。*

v2g6jxz6

v2g6jxz65#

您可以使用游标:

BEGIN; -- open a transaction to extend the scope visibility of the cursor

DO $$
DECLARE
  _cursor cursor FOR select * from my_table;
BEGIN
  OPEN _cursor;
END
$$;

FETCH ALL FROM _cursor;

ABORT;

字符串

相关问题