Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编写/调试复杂PL/pgSQL查询的最佳实践_Sql_Postgresql_Plpgsql_Procedural Programming - Fatal编程技术网

编写/调试复杂PL/pgSQL查询的最佳实践

编写/调试复杂PL/pgSQL查询的最佳实践,sql,postgresql,plpgsql,procedural-programming,Sql,Postgresql,Plpgsql,Procedural Programming,简而言之:编写和调试PostgreSQL查询的最佳方法是什么?这些查询使用过程编程技术,例如使用pl/pgsql?我对编写这些类型的过程性查询非常陌生,因此如果我没有找到一个真正简单的解决方案,请提前道歉 具体说明:我正在编写一些相对复杂的SQL查询,它们利用现有的pl/pgsql函数,理想情况下会使用大量变量,使查询易于调试和修改。下面的示例代码非常简单;我的实际用例要复杂得多 我的第一个解决方案是将所有东西都嵌入到函数中,但这太笨重了。由于我必须显式声明返回类型,因此修改代码非常困难: CR

简而言之:编写和调试PostgreSQL查询的最佳方法是什么?这些查询使用过程编程技术,例如使用pl/pgsql?我对编写这些类型的过程性查询非常陌生,因此如果我没有找到一个真正简单的解决方案,请提前道歉

具体说明:我正在编写一些相对复杂的SQL查询,它们利用现有的pl/pgsql函数,理想情况下会使用大量变量,使查询易于调试和修改。下面的示例代码非常简单;我的实际用例要复杂得多

我的第一个解决方案是将所有东西都嵌入到函数中,但这太笨重了。由于我必须显式声明返回类型,因此修改代码非常困难:

CREATE OR REPLACE FUNCTION 
my_schema.my_fcn()
RETURNS TABLE(user_id integer, 
              id integer, 
              created_at timestamp) AS
$BODY$
DECLARE
    _id_select integer = 10;
BEGIN
    RETURN QUERY
        SELECT 
            user_id, 
            id,
            created_at
        WHERE id = _id_selector
        -- possibly a ton of other complicated stuff involving other functions and variables
        FROM my_schema.my_other_fcn()

END;
$BODY$
LANGUAGE plpgsql;
编辑:使查询变得更加重要

现在假设我想将order_total添加到查询中并去掉id:那么我必须修改退货类型。这种情况会经常发生,而且必须一次又一次地更改返回类型是很烦人的

我尝试的下一个解决方案是不使用函数,并尝试以下方法: 这也不起作用:

DO $$ 
DECLARE
    _id_select integer = 10;
BEGIN
  SELECT 
      user_id, 
      id,
      created_at
  WHERE id = _id_selector
  -- possibly a ton of other complicated stuff involving other functions and variables
  FROM my_schema.my_other_fcn()
END $$;
由此产生的错误:

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 inline_code_block line 4 at SQL statement
********** Error **********

ERROR: query has no destination for result data
我不想使用PERFORM,因为实际上,我希望看到查询的结果


对于这种类型的SQL编程,有一种优雅和/或标准的解决方案吗?

为什么不直接调用plpgsql函数

只做:

SELECT user_id, id, created_at -- possibly a ton of other complicated stuff involving other functions and variables FROM my_schema.my_other_fcn() 我不喜欢这种类型的plpgsql编程包装查询。您可以阻止非常有效的planner—因为plpgsql函数是优化器的黑盒—所以您可能会在大数据上遇到可怕的性能问题。PLpgSQL函数不应替代视图


语句不应返回任何结果。简单-PostgreSQL函数不应替代PostgreSQL视图。

像这样直接调用嵌入函数作为查询,据我所知,不允许在查询中使用变量、循环等。这就是作者的意图——可能是一大堆涉及其他函数和变量的复杂东西。关于性能,在本文中我并不关心这一点。如果您需要变量、循环和可能的返回,那么您需要使用函数—DO语句太有限—并且没有任何其他可能性。