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')
我正在尝试将 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')