Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.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 如何重新检查使用check\u function\u bodies=false创建的SQL函数?_Postgresql_Plpgsql_Syntax Checking - Fatal编程技术网

Postgresql 如何重新检查使用check\u function\u bodies=false创建的SQL函数?

Postgresql 如何重新检查使用check\u function\u bodies=false创建的SQL函数?,postgresql,plpgsql,syntax-checking,Postgresql,Plpgsql,Syntax Checking,接下来,我了解到可以通过设置check\u function\u body=false来禁用SQL函数的语法检查 在我的例子中:使用Flyway where运行升级 函数创建的顺序没有很好的定义 某些函数使用同一升级中尚未创建的其他函数 我的问题是——一旦所有其他依赖项都就绪,是否可以在不需要实际调用的情况下对此类函数进行“重新检查”? 类似于Oracle的alter函数。。。编译 理想情况下,我希望在升级开始时设置check\u function\u bodies=false,然后在升级结束时

接下来,我了解到可以通过设置
check\u function\u body=false来禁用SQL函数的语法检查

在我的例子中:使用Flyway where运行升级

  • 函数创建的顺序没有很好的定义
  • 某些函数使用同一升级中尚未创建的其他函数
  • 我的问题是——一旦所有其他依赖项都就绪,是否可以在不需要实际调用的情况下对此类函数进行“重新检查”? 类似于Oracle的
    alter函数。。。编译

    理想情况下,我希望在升级开始时设置
    check\u function\u bodies=false
    ,然后在升级结束时重新检查每个SQL函数

    我想避免不得不:

  • 控制脚本的运行顺序
  • 重新运行函数创建脚本
  • 我尝试过的事情:

    • 执行虚拟
      alter函数
    • 调用
      pg_get_functiondef

      • 我可以想出两种方法:

      • 您可以直接调用语言验证程序函数:

        SELECT lanname, lanvalidator::regprocedure FROM pg_language;
        
          lanname   |         lanvalidator         
        ------------+------------------------------
         internal   | fmgr_internal_validator(oid)
         c          | fmgr_c_validator(oid)
         sql        | fmgr_sql_validator(oid)
         plpgsql    | plpgsql_validator(oid)
         plpython3u | plpython3_validator(oid)
        (5 rows)
        
        对于SQL函数,其工作原理如下:

        SET check_function_bodies = off;
        CREATE FUNCTION bad() RETURNS void LANGUAGE sql AS 'SELECT $1';
        
        SET check_function_bodies = on;
        SELECT fmgr_sql_validator('bad()'::regprocedure);
        
        ERROR:  there is no parameter $1
        LINE 1: SELECT $1
                       ^
        QUERY:  SELECT $1
        
      • 您可以重新定义函数并检查它是否引发错误:

        SET check_function_bodies = on;
        DO $$BEGIN
           EXECUTE pg_get_functiondef('bad()'::regprocedure);
        END;$$;
        

      • 根据Laurenz的精彩回答,我写了这个小助手函数-为了他人的利益而共享

        CREATE OR REPLACE FUNCTION recompile_functions()
        RETURNS void
        LANGUAGE plpgsql
        VOLATILE
        AS $$
        DECLARE
            l_func regproc;
        BEGIN
            --schema name can also be an input param or current_schema.
            --test sql functions
            FOR l_func IN (
                SELECT oid
                FROM pg_proc
                WHERE pronamespace='my_schema'::regnamespace
                AND prolang=(SELECT oid FROM pg_language WHERE lanname='sql')
            ) 
            LOOP
                PERFORM fmgr_sql_validator(l_func);
            END LOOP;
        
            --test plpgsql functions
            FOR l_func IN (
                SELECT oid
                FROM pg_proc
                WHERE pronamespace='my_schema'::regnamespace
                AND prolang=(SELECT oid FROM pg_language WHERE lanname='plpgsql')
            ) 
            LOOP
                PERFORM plpgsql_validator(l_func);
            END LOOP;
        
        EXCEPTION
            WHEN OTHERS THEN
                RAISE EXCEPTION 'Function % failed validation checks: %', l_func::text, SQLERRM;
        END; $$;
        

        我的博士后在RDS上。根据
        plpgsql\u,不支持check
        坏运气。实际上,对于SQL函数,您可以直接调用验证器。看我编辑的答案。太棒了!正是我想要的。那$$begin执行pg_get_functiondef('bad'::regproc)呢;完(元)-归功于?另一个想法:我没有看到此函数的任何文档。您认为在生产数据库上使用它“安全”吗?在未来的版本中是否保证向后兼容?它看起来像是
        选择plpgsql\u验证器('some_plpgsql\u func'::regproc)
        在函数确实是
        plpgsql
        时从sql工作。您发布的错误是当您尝试使用它验证
        sql
        函数时-我建议您相应地编辑答案。