Lan*_*nti 4 postgresql plpgsql
我正在尝试SELECT使用CREATE PROCEDUREPostgreSQL 11 中的新方法存储一个简单的查询。我的想法是将查询存储在数据库中,因为我的 API 服务器中可以有一个非常简单的代码,也许我不需要开发一个查询生成器是否可以在具有强制类型安全的 sql 函数中使用 if/else。我有这个最小的例子:
首先我尝试了这个 plpgsql 函数:
CREATE OR REPLACE PROCEDURE test_proc() AS $$
BEGIN
SELECT * FROM my_db
LIMIT 1;
END;
$$ LANGUAGE plpgsql;
CALL test_proc();
Run Code Online (Sandbox Code Playgroud)
但是抛出这个错误:
ERROR: 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 test_proc() line 3 at SQL statement SQL state: 42601
如果我尝试使用RETURN QUERY:
CREATE OR REPLACE PROCEDURE test_proc() AS $$
BEGIN
RETURN QUERY;
SELECT * FROM my_db
LIMIT 1;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
ERROR: cannot use RETURN QUERY in a non-SETOF function
LINE 17: RETURN QUERY; ^
SQL state: 42804
Character: 310
当我尝试使用RETURNS void AS $$or时,我也遇到错误RETURNS table(...) AS $$。好像RETURNS不支持CREATE PROCEDURE?那么,是否可以使用新的存储过程方法返回一个表?或者如果不是,也许是 JSON?
PostgreSQL(Oracle、DB2)中的过程与 MS-SQL 中的过程不同。它有不同的目标,你不能使用它。通常,你能做的最好的事情,忘记了你从 MSSQL 中知道的所有内容。程序部分确实不同。
只有函数可以返回一些数据——所以你需要使用函数。函数可以返回标量值、复合值或数组值或表。你想要返回表的函数。
CREATE OR REPLACE FUNCTION fx()
RETURNS SETOF mytab AS $$
BEGIN
RETURN QUERY SELECT * FROM mytab;
END
$$ LANGUAGE plpgsql;
SELECT * FROM fx();
Run Code Online (Sandbox Code Playgroud)
备案:
您可以使用 SQL 函数,它可以有更好(或更差)的性能(取决于上下文)。这些函数有时被命名为参数化视图。
CREATE OR REPLACE FUNCTION fx()
RETURNS SETOF mytab AS $$
SELECT * FROM mytab;
$$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
注意:这个技术是反模式!!!不要这样做。这真的不是一个好主意。函数不应包装查询。如果你想隐藏一些复杂的查询,那么使用视图。不要使用函数。函数是查询优化器的有效屏障,当您使用此反模式时,优化器无法很好地优化以这种形式评估子查询使用的任何非平凡查询。
使用它——如果你想要非常非常慢的应用程序——或者如果你的数据模型或查询是原始的。在其他情况下,不要这样做。
不要害怕 SQL - 它是专为手动使用而设计的优秀语言。将所有数据访问放在一个模块(模型)上是好的,不要在代码中的任何地方访问数据库,但在代码中隐藏 SQL 是不好的。
| 归档时间: |
|
| 查看次数: |
8090 次 |
| 最近记录: |