Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.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
是否可以找到PostgreSQL函数之间的依赖关系?_Sql_Postgresql - Fatal编程技术网

是否可以找到PostgreSQL函数之间的依赖关系?

是否可以找到PostgreSQL函数之间的依赖关系?,sql,postgresql,Sql,Postgresql,我正在使用PostgreSQL9.2.10 假设您有两个PostgreSQL函数,“called_function”和“caller_function”,第二个函数调用第一个函数。确切地说: CREATE FUNCTION called_function () RETURNS varchar AS $BODY$ BEGIN RETURN 'something'; END; CREATE FUNCTION caller_function () RETURNS varchar AS $BODY

我正在使用PostgreSQL9.2.10

假设您有两个PostgreSQL函数,“called_function”和“caller_function”,第二个函数调用第一个函数。确切地说:

CREATE FUNCTION called_function () RETURNS varchar AS
$BODY$
BEGIN
  RETURN 'something';
END;

CREATE FUNCTION caller_function () RETURNS varchar AS
$BODY$
BEGIN
  RETURN called_function ();
END;
现在,使用SQL并只知道函数名,我想知道“caller\u function”是否调用其他函数。或者如果“调用的函数”被其他函数调用。可能吗

我尝试获取函数的OID(假设它是'123'),然后查看pg_depend表:

SELECT * FROM pg_catalog.pg_depend dep WHERE dep.objid = 123 OR dep.objsubid = 123 OR dep.refobjid = 123 OR dep.refobjsubid = 123 OR dep.refobjsubid = 123;

但它只找到pg_语言pg_名称空间依赖项。仅此而已。

查看表格pg_proc,例如:

select nspname,proname,prosrc from pg_proc join  pg_namespace nsp on (pronamespace=nsp.oid) where prosrc like '%called_function%'

我在定义一个函数时遇到了同样的问题,但由于依赖关系,它无法工作。然后,我解决了在命令之前添加此命令的问题

SET check_function_bodies = false;

希望帮助别人

一般情况下不可能;但是一个有限的(受限域)解决方案是完全可行的——并且可能被证明足以满足您的需求

(众多限制中最明显的一个)限制

  • 如果被调用方(要调用的函数)的名称被指定为带引号的标识符,则失败(假阴性)
  • 如果被调用方的名称作为参数传递,则失败(假阴性)
  • 如果在运行时从关系中读取被调用方的名称,则失败(假阴性)
  • 如果被调用方的名称是从令牌组装而来,则失败(假阴性)
  • 若被调用方的名称与文字相同,则失败(误报)
  • 如果多行注释中存在被调用方的名称,则失败(误报)
  • 不考虑函数重载
  • 不考虑通过触发器调用的函数
  • 不考虑根据查询重写规则调用的函数
  • 不考虑查询重写规则的影响
  • 对用C等非解释PLs编写的函数一无所知
样本输出

您的日常工作…|。。。调用这些例程:

--------------------------------------+------------------------------------

create_silo_index{get_config_f_l_ea_silo,subst_silo_id}

demux\uuu id\u创建线程{}

grow\uuu sensor\u thu124;{containing\uh\uu t\u begin}

SQL

它的工作原理

  • #0收集可能是调用者和/或被调用者的所有例程的名称。无论如何,我们都无法正确处理重载函数,因此只需
    DISTINCT
    ,以避免以后的麻烦;SQL是不区分大小写的,除了带引号的标识符之外,我们无论如何都不会去处理它们,所以我们只是
    Lower()
    来简化后面的比较
  • #1
    PG_Get_Functiondef()
    获取
    创建函数
    创建过程
    命令的完整文本。同样,
    Lower()
  • #2去除单行注释。注意懒惰(非贪婪)
    *?
    量词:通常的
    *
    量词,如果在这里使用,将删除第一行注释和所有后续行
  • #3将字母和数字以外的所有字符和
    替换为空格。请注意
    +
    量词:它确保2个以上连续删除的字符仅替换为1个空格
  • #4按空格分割成一个数组;这个数组包含一些SQL语法、文字、数字和标识符,包括例程名称
  • #5将数组卸载到行集中
  • #6
    与例程名称相交
    ;结果将仅由例程名称组成
  • #7将行集转换为数组
  • #8由于输入是
    创建函数f…
    命令的完整文本,因此提取的例程名称显然包含
    f
    本身;因此,我们使用
    Array\u remove()
    删除它



(用PostgreSQL 12.1测试SQL)

我认为这是不可能的。此外,postgres支持不同的语言,包括C语言,在这些语言中查找依赖项并不容易。我可以想到plpgsql和sql函数的一种解决方法:您可以搜索pg_proc表,例如:
select oid,proname from pg_proc,prosrc不为null,prosrc类似“%”
。但这不是一个非常可靠的方法!我猜答案是否定的,Postgress不跟踪函数依赖关系,这就是为什么你可以创建一个依赖于另一个不存在的函数的函数。。。因为它在运行时会爆炸#悲哀的
WITH routine_names AS (
    SELECT DISTINCT(Lower(proname)) AS name                              --#0
    FROM pg_proc
    WHERE proowner = To_Regrole(current_role)
)
SELECT
    name AS "Your routine...",
    Array_Remove(                                                        --#8
        Array(                                                           --#7
            SELECT Unnest(                                               --#5
                String_To_Array(                                         --#4
                    Regexp_Replace(                                      --#3
                        Regexp_Replace(                                  --#2
                            Lower(PG_Get_Functiondef(To_Regproc(name)))  --#1
                            , '--.*?\n', '', 'g'
                        )
                        , '\W+', ' ', 'g'
                    )
                    , ' '
                )
            )
            INTERSECT                                                    --#6
            SELECT name FROM routine_names
            ORDER BY 1
        )
        , name
    ) AS "...calls these routines:"
FROM
    routine_names;