Ste*_*son 43 postgresql dynamic-sql plpgsql sql-drop
我将所有功能都保存在一个文本文件中'CREATE OR REPLACE FUNCTION somefunction'
.因此,如果我添加或更改某些功能,我只需将文件提供给psql.
现在,如果我向现有函数添加或删除参数,它会创建一个具有相同名称的重载,并按照确切的顺序删除所有参数类型中的原始I类型,这是一种单调乏味的操作.
是否有某种通配符,我可以使用DROP具有给定名称的所有函数,所以我可以添加DROP FUNCTION
行到我的文件的顶部?
Erw*_*ter 68
此查询创建所有必需的DDL语句(使用强制转换为简化regprocedure
):
SELECT 'DROP FUNCTION ' || oid::regprocedure
FROM pg_proc
WHERE proname = 'my_function_name' -- name without schema-qualification
AND pg_function_is_visible(oid); -- restrict to current search_path ..
-- .. you may or may not want this
Run Code Online (Sandbox Code Playgroud)
输出:
DROP FUNCTION my_function_name(string text, form text, maxlen integer);
DROP FUNCTION my_function_name(string text, form text);
DROP FUNCTION my_function_name(string text);
Run Code Online (Sandbox Code Playgroud)
执行命令(在合理性检查之后).
函数名称区分大小写,并且在作为text
参数匹配时传递时没有添加双引号pg_proc.proname
.
对象标识符type regprocedure
(oid::regprocedure
)的强制转换使得所有标识符都可以安全地防止SQL注入(通过恶意格式错误的标识符).转换为时text
,函数名称将根据search_path
需要自动根据当前双引号和模式限定.
pg_function_is_visible(oid)
将选择限制为当前的功能search_path
.你可能想要也可能不想要那样.在条件pg_function_is_visible(oid)
到位的情况下,保证功能可见.
如果在多个模式中有多个相同名称的函数,或者具有各种函数参数的重载函数,则所有这些函数将单独列出.您可能希望限制为特定架构或特定功能参数.
有关:
您可以plpgsql
围绕此构建一个函数来立即执行语句EXECUTE
.对于Postgres 9.1或更高版本:
小心!它会降低你的功能!
CREATE OR REPLACE FUNCTION f_delfunc(_name text, OUT func_dropped int) AS
$func$
DECLARE
_sql text;
BEGIN
SELECT count(*)::int
, 'DROP FUNCTION ' || string_agg(oid::regprocedure::text, '; DROP FUNCTION ')
FROM pg_proc
WHERE proname = _name
AND pg_function_is_visible(oid)
INTO func_dropped, _sql; -- only returned if trailing DROPs succeed
IF func_dropped > 0 THEN -- only if function(s) found
EXECUTE _sql;
END IF;
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
呼叫:
SELECT * FROM f_delfunc('my_function_name');
Run Code Online (Sandbox Code Playgroud)
要不就:
SELECT f_delfunc('my_function_name');
Run Code Online (Sandbox Code Playgroud)
这样您就不会获得结果列的列名 func_dropped
.对你来说可能无关紧要.
该函数返回找到和删除的函数数(没有异常引发) - 0
如果没有找到.
它假定一个(默认)search_path
,其中pg_catalog
尚未搬来搬去.
更多相关答案:
对于Postgres版本早于9.1或更早版本的函数使用regproc
并pg_get_function_identity_arguments(oid)
检查此答案的编辑历史记录.
Pau*_*ora 22
您需要编写一个带有函数名称的函数,并使用其参数类型查找每个重载information_schema
,然后DROP
为每个重载生成并执行a .
编辑:事实证明这比我想象的要困难得多.看起来information_schema
似乎没有在其routines
目录中保留必要的参数信息.所以你需要使用PostgreSQL的补充表pg_proc
和pg_type
:
CREATE OR REPLACE FUNCTION udf_dropfunction(functionname text)
RETURNS text AS
$BODY$
DECLARE
funcrow RECORD;
numfunctions smallint := 0;
numparameters int;
i int;
paramtext text;
BEGIN
FOR funcrow IN SELECT proargtypes FROM pg_proc WHERE proname = functionname LOOP
--for some reason array_upper is off by one for the oidvector type, hence the +1
numparameters = array_upper(funcrow.proargtypes, 1) + 1;
i = 0;
paramtext = '';
LOOP
IF i < numparameters THEN
IF i > 0 THEN
paramtext = paramtext || ', ';
END IF;
paramtext = paramtext || (SELECT typname FROM pg_type WHERE oid = funcrow.proargtypes[i]);
i = i + 1;
ELSE
EXIT;
END IF;
END LOOP;
EXECUTE 'DROP FUNCTION ' || functionname || '(' || paramtext || ');';
numfunctions = numfunctions + 1;
END LOOP;
RETURN 'Dropped ' || numfunctions || ' functions';
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Run Code Online (Sandbox Code Playgroud)
我在一个重载函数上成功测试了这个.它被拼凑得非常快,但作为实用功能可以正常工作.我建议在实践中使用它之前测试更多,以防我忽略了一些东西.
改进原始答案以考虑schema
到,即。schema.my_function_name
,
select
format('DROP FUNCTION %s(%s);',
p.oid::regproc, pg_get_function_identity_arguments(p.oid))
FROM pg_catalog.pg_proc p
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE
p.oid::regproc::text = 'schema.my_function_name';
Run Code Online (Sandbox Code Playgroud)