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

时间:2014-11-23 23:37:20

标签: sql postgresql plpgsql procedural-programming

简而言之:编写和调试使用过程编程技术的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:然后我必须修改返回类型。这将会发生很多事情,并且不得不一遍又一遍地改变返回类型。

我尝试的下一个解决方案是不使用函数,并尝试以下几行:How can I execute pl/pgsql code without creating a function? 这也不起作用:

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编程是否有优雅和/或标准的解决方案?

1 个答案:

答案 0 :(得分:0)

为什么不直接调用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编程 - 包装查询。你可以阻止非常有效的规划器 - 因为plpgsql函数是优化器的黑盒子 - 因此你可以预期大数据上的可怕性能问题。 PLpgSQL函数不应该替换视图。

陈述DO不应该返回任何结果。简单地说 - PostgreSQL函数不应该替代PostgreSQL视图。