我正在尝试在PostgreSQL 11中使用新的SELECT
方法存储一个简单的CREATE PROCEDURE
查询。我的想法是将查询存储在DB中,因为我可以在其中包含一个非常简单的代码我的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();
但是抛出此错误:
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;
我收到此错误:
ERROR: cannot use RETURN QUERY in a non-SETOF function
LINE 17: RETURN QUERY; ^
SQL state: 42804
Character: 310
当我尝试使用RETURNS void AS $$
或RETURNS table(...) AS $$
时也出现错误。似乎RETURNS
不支持CREATE PROCEDURE
吗?因此,是否可以使用新的存储过程方法返回表?或者,如果不是,也许是JSON?
答案 0 :(得分:2)
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();
记录下来:
您可以使用SQL函数,该函数可以具有更好(或更差)的性能(取决于上下文)。这些功能有时称为参数化视图。
CREATE OR REPLACE FUNCTION fx()
RETURNS SETOF mytab AS $$
SELECT * FROM mytab;
$$ LANGUAGE sql;
注意:此技术是反模式!请勿这样做。这真的不是一个好主意。该函数不应包装查询。如果要隐藏查询的某些复杂性,请使用视图。不要使用函数。函数对于查询优化器来说是有效的障碍,而当您使用此反模式时,优化器将无法很好地优化在此形式的子查询中使用的任何非平凡查询。
使用它-如果您想要非常慢的应用程序-或您的数据模型或查询是原始的。在其他情况下,请不要这样做。
不要害怕SQL-这是一种伟大的语言,专为手动使用而设计。最好将所有数据访问都放到一个模块(模型)中,而不是在代码中的任何地方访问数据库,但这很不好,也可能在代码中隐藏SQL。
答案 1 :(得分:0)
postgreSql 11.我们必须创建一个存储过程
答案 2 :(得分:-1)
首先,
创建函数的语法
CREATE or replace function function_name(_parameter varchar)
returns table(col1 varchar, col2 varchar, col3 varchar)
language 'plpgsql'
as $BODY$
BEGIN
return query select a.col1, a.col2, b.col3 from table a
join table2 as b on a.col1 = b.col1;
END;
$BODY$;
您可以像表一样调用函数
select * From function_name('sample data');
创建过程的语法。
CREATE OR REPLACE PROCEDURE procedure_name(_parameter varcar,INOUT result refcursor)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
open result for SELECT , * from sampletable where a = _parameter;
END;
$BODY$;
您可以在交易中使用 call 关键字执行过程
BEGIN;
CALL public.procedure_name( 'sample data', 'test');
fetch all in "test";
COMMIT;