gpt4 book ai didi

sql - 删除命名空间中的所有函数? (执行生成的 DDL 命令?)

转载 作者:行者123 更新时间:2023-11-29 11:34:41 25 4
gpt4 key购买 nike

我正在尝试编写一个命令来删除命名空间中的所有函数。我已经找到了一个可以生成 drop 函数脚本的命令:

SELECT 'DROP FUNCTION ' || ns.nspname || '.' || proname || '('
|| oidvectortypes(proargtypes) || ');'
FROM pg_proc INNER JOIN pg_namespace ns ON (pg_proc.pronamespace = ns.oid)
WHERE ns.nspname = 'public' order by proname;

来源:http://www.postgresonline.com/journal/archives/74-How-to-delete-many-functions.html

这将生成如下内容:

                 ?column?                 
------------------------------------------
DROP FUNCTION public.function1(bigint);
DROP FUNCTION public.function2();
DROP FUNCTION public.function3(text);

但是,我不知道如何更改代码,以便实际删除函数 - 而不是仅生成命令。

有什么想法吗?

最佳答案

系统目录在 Postgres 11 中发生了变化! (prokind 而不是 proisagg)参见:


可能看起来像这样:

CREATE OR REPLACE FUNCTION public.f_delfunc(_schema text, _del text = '')
RETURNS text AS
$func$
DECLARE
_sql text;
_ct text;
BEGIN
SELECT INTO _sql, _ct
string_agg('DROP '
|| CASE p.proisagg WHEN true THEN 'AGGREGATE '
ELSE 'FUNCTION ' END
|| quote_ident(n.nspname) || '.' || quote_ident(p.proname)
|| '('
|| pg_catalog.pg_get_function_identity_arguments(p.oid)
|| ')'
, E'\n'
)
,count(*)::text
FROM pg_catalog.pg_proc p
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = _schema;
-- AND p.proname ~~* 'f_%'; -- Only selected funcs?
-- AND pg_catalog.pg_function_is_visible(p.oid) -- Only visible funcs?

IF _ct = '0' THEN
RETURN 'Found 0 functions to delete';
ELSIF lower(_del) = 'del' THEN -- Actually delete!
EXECUTE _sql;
RETURN _ct || E' functions deleted:\n' || _sql;
ELSE -- Else only show SQL.
RETURN _ct || E' functions to delete:\n' || _sql;
END IF;
END
$func$ LANGUAGE plpgsql;

调用显示:

SELECT f_delfunc('public');         -- 2nd parameter is covered by default.

调用删除:

SELECT f_delfunc('public','del');

要点

  • 为此您需要动态 SQL。使用 plpgsql functionDO statement (PostgreSQL 9.0+) 使用 EXECUTE

  • 注意 functions pg_get_function_identity_arguments() and pg_function_is_visible 的使用.后者可以省略。这是一种保护措施,因此您不会删除当前用户的 search_path 之外的函数。

  • 我添加了“安全模式”。仅在 $2 = 'del' 时删除。否则只显示生成的 SQL。

  • 请注意,如果函数存在于您从中删除的模式中,它将自行删除

  • 我还添加了 quote_ident() 来防范 SQLi。请考虑以下事项:

CREATE FUNCTION "; DELETE FROM users;"()
RETURNS int AS
'SELECT 1'
LANGUAGE sql;
  • 如果对任何涉及的函数有依赖性,这将失败。可以通过添加 CASCADE 来解决,但我没有在这里这样做,因为它会使函数更加危险。

相关:

关于sql - 删除命名空间中的所有函数? (执行生成的 DDL 命令?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8317775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com