当我的PLPGSQL
函数(Postgres 9.6)中的语句正在运行时,我可以在一行上看到查询,然后在另一行上看到所有参数。 2行记录。类似的东西:
LOG: execute <unnamed>: SELECT * FROM table WHERE field1=$1 AND field2=$2 ...
DETAIL: parameters: $1 = '-767197682', $2 = '234324' ....
是否可以在pg_log WITH 中记录查询中已替换的参数的整个查询,并将其记录在 SINGLE 行中?
因为这样可以更容易地复制/粘贴查询以在另一个终端中重现它,特别是如果查询有许多参数。
答案 0 :(得分:1)
背后的原因:PL / pgSQL在内部将SQL语句视为 预备语句 。
首先:使用默认设置,PL / pgSQL函数中的SQL语句有 无 记录。您使用的是auto_explain
吗?
在同一会话中的前几次调用中,SPI管理器(服务器编程接口)基于实际参数值生成新的执行计划。任何类型的日志记录都应报告参数值内联。
Postgres会跟踪并在当前会话中进行几次调用后,如果执行计划似乎对实际参数值不敏感,它将开始重用通用的缓存计划。然后,您应该看到带有$n
参数的预准备语句的通用计划(如问题中所示)。
chapter "Plan Caching" in the manual中的详细信息。
您可以通过简单的演示观察效果。在同一个会话中(不一定是同一个交易):
CREATE TEMP TABLE tbl AS
SELECT id FROM generate_series(1, 100) id;
PREPARE prep1(int) AS
SELECT min(id) FROM tbl WHERE id > $1;
EXPLAIN EXECUTE prep1(3); -- 1st execution
您将看到实际值:
Filter: (id > 3)
EXECUTE prep1(1); -- several more executions
EXECUTE prep1(2);
EXECUTE prep1(3);
EXECUTE prep1(4);
EXECUTE prep1(5);
EXPLAIN EXECUTE prep1(3);
现在您将看到$n
参数:
Filter: (id > $1)
因此,您可以在当前会话的前几次调用中使用参数值 inlined 获取查询。
或者您可以将动态SQL与EXECUTE
一起使用,因为per documentation:
此外,对于通过
EXECUTE
执行的命令,还有无计划缓存。 相反,每次运行语句时都会计划命令。 因此,可以在函数内动态创建命令字符串 对不同的表和列执行操作。
当然,这实际上会影响表现。
相关: