如何从函数本身内部获取调用函数的语句?

时间:2012-10-26 18:18:06

标签: postgresql stored-procedures plpgsql postgresql-9.1

假设我有一个函数show_files(IN file text, IN suffix text, OUT statement text)。在下一步中,该函数被调用:

 SELECT * FROM show_files(file := 'example', suffix := '.png');

我的问题是:是否有任何解决方案可以从该函数内部调用此函数?

我的意思是,在运行SELECT之后,函数(OUT statement text)的输出应该是:'SELECT * FROM show_files(file := 'example', suffix := '.png');',还是可以将此语句赋值给函数内的变量?

我需要在触发程序中使用TG_NAMETG_OP等功能。

也许可以从SELECT current_query FROM pg_stat_activity中检索这个语句吗?

当我试图在一个函数中使用它时,我有一个空记录:

CREATE OR REPLACE FUNCTION f_snitch(text)
  RETURNS text AS
$BODY$
declare
rr text;
BEGIN
    RAISE NOTICE '.. from f_snitch.';
    -- do stuff
    SELECT current_query  into rr FROM pg_stat_activity 
    WHERE current_query ilike 'f_snitch';
    RETURN rr;
END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

欢迎任何帮助和建议!

2 个答案:

答案 0 :(得分:1)

TG_NAME和朋友是仅存在于触发器功能的特殊变量。常规plpgsql函数没有这样的东西。我很想你如何在plpgsql中的调用函数中获取它。

可以RAISE NOTICE添加到您的功能中,以便获得所需的信息

CREATE OR REPLACE FUNCTION f_snitch(text)
  RETURNS text LANGUAGE plpgsql AS
$func$
BEGIN
    RAISE NOTICE '.. from f_snitch.';
    -- do stuff
    RETURN 'Snitch says hi!';
END
$func$;

呼叫:

SELECT f_snitch('foo')

除结果外,还会返回通知:

NOTICE:  .. from f_snitch.

在两个方面未能取悦:

  1. 呼叫声明不在通知中。
  2. 通知中没有 CONTEXT
  3. 对于 1。,您可以使用 RAISE LOG (或者将您的群集设置为记录通知 - 我通常不会这样做,太冗长为了我)。使用标准设置,您将在数据库日志中获得STATEMENT的附加行:

    LOG:  .. from f_snitch.
    STATEMENT:  SELECT f_snitch('foo')
    

    对于 2。,请查看此related question at dba.SECONTEXT看起来像是:

    CONTEXT:  SQL statement "SELECT f_raise('LOG', 'My message')"
        PL/pgSQL function "f_snitch" line 5 at PERFORM
    

答案 1 :(得分:0)

好的,我知道了!

CREATE OR REPLACE FUNCTION f_snitch(text)
  RETURNS setof record AS
$BODY$
BEGIN
   RETURN QUERY
    SELECT current_query 
    FROM pg_stat_activity 
    <strike>ORDER BY length(current_query) DESC LIMIT 1;</strike>
    where current_query ilike 'select * from f_snitch%';
    -- much more reliable solution

END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

  select * from f_snitch('koper') AS (tt text);

结果如下:

enter image description here

这可能不是100%可靠的解决方案,但对于小型系统(对于少数用户而言),这是非常好的。