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
函数时-我建议您相应地编辑答案。