在 Postgres 函数中访问 Return Table
Accessing the Return Table in a Postgres Function
在 MSSQL 中,当在多语句 table 值函数中时,您可以使用 table 进行交互,如下所示。
CREATE FUNCTION dbo.test_func() RETURNS @table TABLE(id INT) AS
BEGIN
INSERT INTO @table(id)
SELECT 1 UNION SELECT 2 UNION SELECT 3
UPDATE @table SET id = -1 WHERE id = 3
RETURN
END
GO
有没有办法在 Postgres 9.5 中完成此操作?我不确定要更新什么,如下所示。
CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
return QUERY SELECT 1 UNION SELECT 2 UNION SELECT 3;
UPDATE ???? SET id = -1 WHERE id = 3;
END;
$$ LANGUAGE plpgsql STABLE;
函数的结果集在使用 RETURN NEXT
or RETURN QUERY
发送后无法更改。
但是在 PostgreSQL 中,您不必在单个语句中发送整个结果集(这就是为什么您的要求在 PostgreSQL 中毫无意义)。您可以使用 RETURN NEXT
将行逐行发送到结果集,您可以使用 RETURN QUERY
/RETURN QUERY EXECUTE
发送结果集的块,或者甚至可以混合使用。 (您也可以使用不带参数的单个 RETURN
退出该函数)。
所以,您可能想要做的是:
CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
RETURN QUERY VALUES (1), (2);
-- do some calculation
RETURN NEXT -1;
END;
$$ LANGUAGE plpgsql STABLE;
如果你真的想模仿what MSSQL does,你可以使用临时表,或者(最好)在函数内部进行子选择:
CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
RETURN QUERY SELECT (SELECT CASE WHEN v = 3 THEN -1 ELSE v END res)
FROM (VALUES (1), (2), (3)) v;
END;
$$ LANGUAGE plpgsql STABLE;
CREATE FUNCTION test_func()
RETURNS TABLE(id int) AS
$func$
BEGIN
RETURN QUERY
SELECT CASE WHEN v = 3 THEN -1 ELSE v END
FROM (VALUES (1), (2), (3)) v;
END
$func$ LANGUAGE plpgsql IMMUTABLE;
根本不需要 PL/pgSQL。一个简单的 SQL 函数就可以做到:
CREATE FUNCTION test_func()
RETURNS SETOF int AS
$func$
SELECT CASE WHEN v = 3 THEN -1 ELSE v END
FROM (VALUES (1), (2), (3)) v;
$func$ LANGUAGE sql IMMUTABLE;
还演示了简单形式 SETOF int
而不是简单情况下的 TABLE(id int)
。您可以使用任何一种。
相关答案(在许多其他人中):
- PostgreSQL function returning multiple result sets
- How to return result of a SELECT inside a function in PostgreSQL?
对于更复杂的操作,您可以使用 CTE
CREATE FUNCTION test_func()
RETURNS SETOF int AS
$func$
WITH v(id) AS (VALUES (1), (2), (3))
SELECT CASE WHEN id = 3 THEN -1 ELSE id END
FROM v
$func$ LANGUAGE sql IMMUTABLE;
对于更复杂的工作,您可以使用实际的 temporary table:
PostgreSQL table variable
Select from a table variable
在 MSSQL 中,当在多语句 table 值函数中时,您可以使用 table 进行交互,如下所示。
CREATE FUNCTION dbo.test_func() RETURNS @table TABLE(id INT) AS
BEGIN
INSERT INTO @table(id)
SELECT 1 UNION SELECT 2 UNION SELECT 3
UPDATE @table SET id = -1 WHERE id = 3
RETURN
END
GO
有没有办法在 Postgres 9.5 中完成此操作?我不确定要更新什么,如下所示。
CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
return QUERY SELECT 1 UNION SELECT 2 UNION SELECT 3;
UPDATE ???? SET id = -1 WHERE id = 3;
END;
$$ LANGUAGE plpgsql STABLE;
函数的结果集在使用 RETURN NEXT
or RETURN QUERY
发送后无法更改。
但是在 PostgreSQL 中,您不必在单个语句中发送整个结果集(这就是为什么您的要求在 PostgreSQL 中毫无意义)。您可以使用 RETURN NEXT
将行逐行发送到结果集,您可以使用 RETURN QUERY
/RETURN QUERY EXECUTE
发送结果集的块,或者甚至可以混合使用。 (您也可以使用不带参数的单个 RETURN
退出该函数)。
所以,您可能想要做的是:
CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
RETURN QUERY VALUES (1), (2);
-- do some calculation
RETURN NEXT -1;
END;
$$ LANGUAGE plpgsql STABLE;
如果你真的想模仿what MSSQL does,你可以使用临时表,或者(最好)在函数内部进行子选择:
CREATE FUNCTION test_func() RETURNS TABLE(id int) AS $$
BEGIN
RETURN QUERY SELECT (SELECT CASE WHEN v = 3 THEN -1 ELSE v END res)
FROM (VALUES (1), (2), (3)) v;
END;
$$ LANGUAGE plpgsql STABLE;
CREATE FUNCTION test_func()
RETURNS TABLE(id int) AS
$func$
BEGIN
RETURN QUERY
SELECT CASE WHEN v = 3 THEN -1 ELSE v END
FROM (VALUES (1), (2), (3)) v;
END
$func$ LANGUAGE plpgsql IMMUTABLE;
根本不需要 PL/pgSQL。一个简单的 SQL 函数就可以做到:
CREATE FUNCTION test_func()
RETURNS SETOF int AS
$func$
SELECT CASE WHEN v = 3 THEN -1 ELSE v END
FROM (VALUES (1), (2), (3)) v;
$func$ LANGUAGE sql IMMUTABLE;
还演示了简单形式 SETOF int
而不是简单情况下的 TABLE(id int)
。您可以使用任何一种。
相关答案(在许多其他人中):
- PostgreSQL function returning multiple result sets
- How to return result of a SELECT inside a function in PostgreSQL?
对于更复杂的操作,您可以使用 CTE
CREATE FUNCTION test_func()
RETURNS SETOF int AS
$func$
WITH v(id) AS (VALUES (1), (2), (3))
SELECT CASE WHEN id = 3 THEN -1 ELSE id END
FROM v
$func$ LANGUAGE sql IMMUTABLE;
对于更复杂的工作,您可以使用实际的 temporary table:
PostgreSQL table variable
Select from a table variable