UDF(User-Defined Functions) 管理
1. 创建函数 (CREATE FUNCTION)
基本语法
CREATE [OR REPLACE] FUNCTION function_name ([parameter_list])
RETURNS return_type
AS $$
# Python 代码
return result
$$ LANGUAGE plpython3u;
示例:
CREATE OR REPLACE FUNCTION calculate_sum(a INTEGER, b INTEGER)
RETURNS INTEGER
AS $$
return a + b
$$ LANGUAGE plpython3u;
参数说明:
OR REPLACE
: 如果函数已存在,则替换它parameter_list
: 参数列表,格式为参数名 数据类型
return_type
: 返回值的数据类型LANGUAGE plpython3u
: 指定使用 PL/Python3 不可信语言
2. 查询函数信息
2.1 查看所有自定义函数
-- 查看所有用户自定义函数
SELECT proname as function_name,
pg_get_function_arguments(oid) as arguments,
pg_get_function_result(oid) as return_type,
prolang::regproc as language
FROM pg_proc
WHERE pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
ORDER BY proname;
2.2 查看特定函数的定义
-- 查看函数的完整定义(包括源代码)
SELECT pg_get_functiondef(oid) as function_definition
FROM pg_proc
WHERE proname = 'calculate_sum';
-- 或者使用 \df+ 命令(在 psql 中)
\df+ calculate_sum
2.3 查看函数的详细信
-- 查看函数的详细信息
SELECT
p.proname as function_name,
pg_get_function_arguments(p.oid) as parameters,
pg_get_function_result(p.oid) as return_type,
l.lanname as language,
p.prosecdef as security_definer,
p.provolatile as volatility,
p.proisstrict as is_strict,
p.proretset as returns_set,
obj_description(p.oid, 'pg_proc') as description
FROM pg_proc p
JOIN pg_language l ON p.prolang = l.oid
WHERE p.proname = 'calculate_sum';
2.4 查看函数依赖关系
-- 查看函数依赖的对象
SELECT
dep.classid::regclass,
dep.objid::regproc,
dep.objsubid,
dep.refclassid::regclass,
dep.refobjid,
dep.refobjsubid,
dep.deptype
FROM pg_depend dep
JOIN pg_proc p ON p.oid = dep.objid
WHERE p.proname = 'your_function_name';
3. 删除函数 (DROP FUNCTION)
3.1 基本语法
DROP FUNCTION [IF EXISTS] function_name ([parameter_types]);
3.2 删除示例
删除无参数函数:
-- 删除无参数函数
DROP FUNCTION get_current_timestamp();
-- 安全删除(如果存在)
DROP FUNCTION IF EXISTS get_current_timestamp();
删除带参数函数:
-- 删除带参数函数,需要指定参数类型
DROP FUNCTION calculate_sum(INTEGER, INTEGER);
-- 安全删除
DROP FUNCTION IF EXISTS calculate_sum(INTEGER, INTEGER);
删除重载函数: 当有多个同名函数但参数不同时,需要指定具体的参数类型:
-- 假设有两个重载函数
CREATE FUNCTION process_data(data TEXT) RETURNS TEXT ...
CREATE FUNCTION process_data(data INTEGER) RETURNS TEXT ...
-- 删除特定版本
DROP FUNCTION process_data(TEXT); -- 删除处理文本的版本
DROP FUNCTION process_data(INTEGER); -- 删除处理整数的版本
3.3 批量删除函数
-- 删除所有 PL/Python 函数
DO $$
DECLARE
func_record RECORD;
BEGIN
FOR func_record IN
SELECT p.oid, p.proname, pg_get_function_identity_arguments(p.oid) as args
FROM pg_proc p
JOIN pg_language l ON p.prolang = l.oid
WHERE l.lanname = 'plpython3u'
AND p.pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
LOOP
EXECUTE format('DROP FUNCTION %I(%s)',
func_record.proname,
func_record.args);
END LOOP;
END $$;
4. 函数修改和重命名
4.1 修改函数(使用 CREATE OR REPLACE)
-- 修改函数实现
CREATE OR REPLACE FUNCTION calculate_sum(a INTEGER, b INTEGER)
RETURNS INTEGER
AS $$
# 修改后的实现
result = a + b
return result
$$ LANGUAGE plpython3u;
4.2 修改函数所有者
-- 修改函数所有者
ALTER FUNCTION add_numbers(INTEGER, INTEGER) OWNER TO new_owner;
5. 函数权限管理
5.1 查看函数权限
-- 查看函数的权限信息
SELECT
proname as function_name,
pronamespace::regnamespace as schema,
proacl as privileges
FROM pg_proc
WHERE proname = 'calculate_sum';
5.2 授予和撤销权限
-- 授予函数执行权限给用户
GRANT EXECUTE ON FUNCTION calculate_sum(INTEGER, INTEGER) TO username;
-- 授予函数执行权限给角色
GRANT EXECUTE ON FUNCTION calculate_sum(INTEGER, INTEGER) TO role_name;
-- 撤销执行权限
REVOKE EXECUTE ON FUNCTION calculate_sum(INTEGER, INTEGER) FROM username;
6. 实用查询示例
6.1 查找所有 PL/Python 函数
SELECT
n.nspname as schema,
p.proname as function_name,
pg_get_function_arguments(p.oid) as parameters,
pg_get_function_result(p.oid) as return_type,
p.prosrc as source_code
FROM pg_proc p
JOIN pg_language l ON p.prolang = l.oid
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE l.lanname = 'plpython3u'
ORDER BY n.nspname, p.proname;
6.2 查找使用特定库的函数
-- 查找使用 numpy 的函数
SELECT
proname as function_name,
pg_get_function_arguments(oid) as parameters
FROM pg_proc
WHERE prosrc LIKE '%import numpy%'
OR prosrc LIKE '%from numpy%'
OR prosrc LIKE '%numpy.%';