Postgres 数据库 "Query has no destination for result data " 错误

Postgres database "Query has no destination for result data " error

我正在尝试将 MSSQL 查询转换为 POSTGRES 查询。 我无法在 Postgres

中执行以下查询
DO $$
BEGIN
IF EXISTS (SELECT ID FROM PROCESS WHERE ID = (SELECT MAX(ID) FROM PROCESS WHERE NAME = 'TRANSACTION')) THEN
SELECT * FROM MSG
WHERE msg_timestamp >= ( SELECT start_time FROM PROCESS WHERE NAME = 'TRANSACTION' AND STATUS = 'STARTED');
ELSE
SELECT * FROM MSG;
END IF;
END $$;

错误:

query has no destination for result data HINT: If you want to discard the results of a SELECT, use PERFORM instead. CONTEXT: PL/pgSQL function inline_code_block line 7 at SQL statement FCMDBPOSTGRES=#

我对应的 MSSQL 查询如下,工作正常

IF EXISTS (SELECT ID FROM PROCESS WHERE ID = (SELECT MAX(ID) FROM PROCESS WHERE NAME = 'TRANSACTION'))
BEGIN
   SELECT * FROM MSG
WHERE msg_timestamp >= ( SELECT start_time FROM PROCESS WHERE NAME = 'TRANSACTION' AND STATUS = 'STARTED')
END
ELSE
BEGIN
    SELECT * FROM MSG
END

无法正常工作。 Postgres 不支持过程或脚本中的自由查询。 SQL 语句的每个结果都应保存到变量中(或作为 table 函数的结果返回)。更多DO语句没有任何输入输出机制。你可以写table函数:

CREATE OR REPLACE FUNCTION fx()
RETURNS SETOF MSG AS $$
BEGIN
  IF EXISTS (SELECT ID FROM PROCESS
              WHERE ID = (SELECT MAX(ID) FROM PROCESS
                           WHERE NAME = 'TRANSACTION'))
  THEN
    RETURN QUERY SELECT * FROM MSG
                    WHERE msg_timestamp >= ( SELECT start_time FROM PROCESS
                            WHERE NAME = 'TRANSACTION' AND STATUS = 'STARTED');
  ELSE
    RETURN QUERY SELECT * FROM MSG;
  END IF;
END
$$ LANGUAGE plpgsql;

SELECT * FROM fx();

注意:如果您有 MSSQL 程序的经验,那么使用 Postgres 的最佳开始是阅读文档 - https://www.postgresql.org/docs/current/plpgsql.html。很多事情都非常不同。 Postgres中的存储过程类似于Oracle,但与MS相去甚远SQL.

你不需要 do 声明,只是简单的 SQL:

SELECT * FROM MSG
WHERE 
    NOT EXISTS (SELECT ID FROM PROCESS WHERE ID = (SELECT MAX(ID) FROM PROCESS WHERE NAME = 'TRANSACTION'))
    OR msg_timestamp >= (SELECT start_time FROM PROCESS WHERE NAME = 'TRANSACTION' AND STATUS = 'STARTED');

或者更详细一点:

SELECT * FROM MSG
WHERE 
    CASE
        WHEN EXISTS (SELECT ID FROM PROCESS WHERE ID = (SELECT MAX(ID) FROM PROCESS WHERE NAME = 'TRANSACTION'))
            THEN msg_timestamp >= (SELECT start_time FROM PROCESS WHERE NAME = 'TRANSACTION' AND STATUS = 'STARTED')
        ELSE TRUE
    END;

或者更简单:

SELECT * FROM MSG
WHERE 
    msg_timestamp >= coalesce(
        (SELECT start_time FROM PROCESS WHERE NAME = 'TRANSACTION' AND STATUS = 'STARTED'),
        '-infinity');

顺便说一句,如果我没理解错的话

EXISTS (SELECT ID FROM PROCESS WHERE ID = (SELECT MAX(ID) FROM PROCESS WHERE NAME = 'TRANSACTION'))

可以简化为

EXISTS (SELECT 1 FROM PROCESS WHERE NAME = 'TRANSACTION')