PostgreSQL教程FG161-PL/pgSQL基础:语法规范与变量/流程控制
本文档风哥主要介绍PostgreSQL数据库PL/pgSQL的基础知识,包括语法规范、变量定义和流程控制,风哥教程参考PostgreSQL官方文档PL/pgSQL内容,适合数据库开发人员和DBA在生产环境中使用PL/pgSQL编写函数和存储过程。
Part01-基础概念与理论知识
1.1 PostgreSQL数据库PL/pgSQL概念
PL/pgSQL是PostgreSQL的过程化编程语言,它允许在数据库中编写复杂的函数和存储过程。更多视频教程www.fgedu.net.cn。
- 支持变量定义和赋值
- 支持流程控制语句(IF、LOOP、WHILE等)
- 支持异常处理
- 支持游标操作
- 支持事务控制
- 与SQL紧密集成
1.2 PostgreSQL数据库PL/pgSQL语法规范
PL/pgSQL的基本语法结构包括:
- 函数定义:使用CREATE FUNCTION语句
- 变量声明:使用DECLARE部分
- 函数体:使用BEGIN…END块
- 语句结束:使用分号(;)
- 注释:使用–或/* */
1.3 PostgreSQL数据库PL/pgSQL变量定义
PL/pgSQL支持多种类型的变量,包括:
- 标量变量:整数、浮点数、字符串、布尔值等
- 复合变量:记录类型、行类型等
- 数组变量:一维或多维数组
- 游标变量:用于结果集处理
Part02-生产环境规划与建议
2.1 PostgreSQL数据库PL/pgSQL设计原则
PL/pgSQL设计原则:单一职责,每个函数只做一件事;模块化设计,便于维护;性能优先,避免复杂逻辑;安全性,避免SQL注入;可读性,编写清晰的代码。
2.2 PostgreSQL数据库PL/pgSQL性能优化
性能优化建议:使用适当的变量类型;避免不必要的计算;使用批量操作;合理使用游标;监控函数执行性能;定期优化代码。
2.3 PostgreSQL数据库PL/pgSQL安全考虑
安全考虑:避免SQL注入;使用参数化查询;限制函数权限;验证输入参数;避免特权操作;定期更新函数以修复安全漏洞。
Part03-生产环境项目实施方案
3.1 PostgreSQL数据库PL/pgSQL变量使用
3.1.1 变量定义与使用
— 创建测试表
CREATE TABLE fgedu_employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
department VARCHAR(100) NOT NULL,
salary NUMERIC(10,2) NOT NULL,
hire_date DATE DEFAULT CURRENT_DATE
);
— 输出结果
CREATE TABLE
— 插入测试数据
INSERT INTO fgedu_employees(name, department, salary)
VALUES
(‘张三’, ‘技术部’, 8000.00),
(‘李四’, ‘销售部’, 6000.00),
(‘王五’, ‘技术部’, 9000.00);
— 输出结果
INSERT 0 3
— 变量定义示例
CREATE OR REPLACE FUNCTION fgedu_test_variables()
RETURNS TEXT
AS $$
DECLARE
— 标量变量
v_id INTEGER := 1;
v_name VARCHAR(100) := ‘张三’;
v_salary NUMERIC(10,2) := 8000.00;
v_active BOOLEAN := TRUE;
v_hire_date DATE := CURRENT_DATE;
— 复合变量
v_employee RECORD;
v_employee_row fgedu_employees%ROWTYPE;
— 数组变量
v_names TEXT[] := ARRAY[‘张三’, ‘李四’, ‘王五’];
v_salaries NUMERIC(10,2)[] := ARRAY[8000.00, 6000.00, 9000.00];
— 游标变量
cur_employees REFCURSOR;
BEGIN
— 变量赋值
v_name := ‘赵六’;
v_salary := v_salary + 1000.00;
— 使用变量
RAISE NOTICE ‘Employee ID: %’, v_id;
RAISE NOTICE ‘Employee Name: %’, v_name;
RAISE NOTICE ‘Employee Salary: %’, v_salary;
RAISE NOTICE ‘Active: %’, v_active;
RAISE NOTICE ‘Hire Date: %’, v_hire_date;
— 访问数组元素
RAISE NOTICE ‘First name: %’, v_names[1];
RAISE NOTICE ‘Second salary: %’, v_salaries[2];
— 获取行数据
SELECT * INTO v_employee_row FROM fgedu_employees WHERE id = v_id;
RAISE NOTICE ‘Employee from row: %, %’, v_employee_row.name, v_employee_row.department;
— 获取记录数据
SELECT id, name, department INTO v_employee FROM fgedu_employees WHERE id = v_id;
RAISE NOTICE ‘Employee from record: %, %’, v_employee.name, v_employee.department;
RETURN ‘Variables test completed’;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试变量函数
SELECT fgedu_test_variables();
— 输出结果
NOTICE: Employee ID: 1
NOTICE: Employee Name: 赵六
NOTICE: Employee Salary: 9000.00
NOTICE: Active: t
NOTICE: Hire Date: 2026-04-08
NOTICE: First name: 张三
NOTICE: Second salary: 6000.00
NOTICE: Employee from row: 张三, 技术部
NOTICE: Employee from record: 张三, 技术部
fgedu_test_variables
———————-
Variables test completed
(1 row)
3.2 PostgreSQL数据库PL/pgSQL流程控制
3.2.1 流程控制语句
— IF语句
CREATE OR REPLACE FUNCTION fgedu_test_if(IN p_salary NUMERIC(10,2))
RETURNS TEXT
AS $$
DECLARE
v_result TEXT;
BEGIN
IF p_salary < 5000 THEN
v_result := '低薪';
ELSIF p_salary < 8000 THEN
v_result := '中薪';
ELSE
v_result := '高薪';
END IF;
RETURN v_result;
END;
$$ LANGUAGE plpgsql;
-- 输出结果
CREATE FUNCTION
-- 测试IF函数
SELECT fgedu_test_if(4000.00);
-- 输出结果
fgedu_test_if
---------------
低薪
(1 row)
SELECT fgedu_test_if(6000.00);
-- 输出结果
fgedu_test_if
---------------
中薪
(1 row)
SELECT fgedu_test_if(9000.00);
-- 输出结果
fgedu_test_if
---------------
高薪
(1 row)
-- LOOP语句
CREATE OR REPLACE FUNCTION fgedu_test_loop(IN p_count INTEGER)
RETURNS INTEGER
AS $$
DECLARE
v_sum INTEGER := 0;
v_i INTEGER := 1;
BEGIN
LOOP
v_sum := v_sum + v_i;
v_i := v_i + 1;
EXIT WHEN v_i > p_count;
END LOOP;
RETURN v_sum;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试LOOP函数
SELECT fgedu_test_loop(10);
— 输出结果
fgedu_test_loop
—————-
55
(1 row)
— WHILE语句
CREATE OR REPLACE FUNCTION fgedu_test_while(IN p_count INTEGER)
RETURNS INTEGER
AS $$
DECLARE
v_sum INTEGER := 0;
v_i INTEGER := 1;
BEGIN
WHILE v_i <= p_count LOOP
v_sum := v_sum + v_i;
v_i := v_i + 1;
END LOOP;
RETURN v_sum;
END;
$$ LANGUAGE plpgsql;
-- 输出结果
CREATE FUNCTION
-- 测试WHILE函数
SELECT fgedu_test_while(10);
-- 输出结果
fgedu_test_while
-----------------
55
(1 row)
-- FOR语句
CREATE OR REPLACE FUNCTION fgedu_test_for(IN p_count INTEGER)
RETURNS INTEGER
AS $$
DECLARE
v_sum INTEGER := 0;
BEGIN
FOR v_i IN 1..p_count LOOP
v_sum := v_sum + v_i;
END LOOP;
RETURN v_sum;
END;
$$ LANGUAGE plpgsql;
-- 输出结果
CREATE FUNCTION
-- 测试FOR函数
SELECT fgedu_test_for(10);
-- 输出结果
fgedu_test_for
---------------
55
(1 row)
-- FOREACH语句(数组遍历)
CREATE OR REPLACE FUNCTION fgedu_test_foreach()
RETURNS TEXT
AS $$
DECLARE
v_names TEXT[] := ARRAY['张三', '李四', '王五'];
v_name TEXT;
v_result TEXT := '';
BEGIN
FOREACH v_name IN ARRAY v_names LOOP
v_result := v_result || v_name || ', ';
END LOOP;
-- 去除末尾的逗号和空格
v_result := rtrim(v_result, ', ');
RETURN v_result;
END;
$$ LANGUAGE plpgsql;
-- 输出结果
CREATE FUNCTION
-- 测试FOREACH函数
SELECT fgedu_test_foreach();
-- 输出结果
fgedu_test_foreach
-------------------
张三, 李四, 王五
(1 row)
3.3 PostgreSQL数据库PL/pgSQL错误处理
3.3.1 错误处理
— 异常处理
CREATE OR REPLACE FUNCTION fgedu_test_exception(IN p_id INTEGER)
RETURNS TEXT
AS $$
DECLARE
v_name VARCHAR(100);
BEGIN
BEGIN
SELECT name INTO v_name FROM fgedu_employees WHERE id = p_id;
RETURN ‘Employee found: ‘ || v_name;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN ‘Employee not found’;
WHEN OTHERS THEN
RETURN ‘Error: ‘ || SQLERRM;
END;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试异常处理函数
SELECT fgedu_test_exception(1);
— 输出结果
fgedu_test_exception
———————-
Employee found: 张三
(1 row)
SELECT fgedu_test_exception(999);
— 输出结果
fgedu_test_exception
———————-
Employee not found
(1 row)
— 自定义异常
CREATE OR REPLACE FUNCTION fgedu_test_custom_exception(IN p_salary NUMERIC(10,2))
RETURNS TEXT
AS $$
BEGIN
IF p_salary < 0 THEN
RAISE EXCEPTION 'Salary cannot be negative';
ELSIF p_salary > 100000 THEN
RAISE EXCEPTION ‘Salary too high’;
END IF;
RETURN ‘Valid salary: ‘ || p_salary;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试自定义异常函数
SELECT fgedu_test_custom_exception(5000.00);
— 输出结果
fgedu_test_custom_exception
—————————–
Valid salary: 5000.00
(1 row)
SELECT fgedu_test_custom_exception(-1000.00);
— 输出结果
ERROR: Salary cannot be negative
SELECT fgedu_test_custom_exception(200000.00);
— 输出结果
ERROR: Salary too high
Part04-生产案例与实战讲解
4.1 PostgreSQL数据库PL/pgSQL基础实战
本案例演示PL/pgSQL的基础使用。学习交流加群风哥QQ113257174。
— 创建员工管理函数
CREATE OR REPLACE FUNCTION fgedu_get_employee_by_id(IN p_id INTEGER)
RETURNS fgedu_employees%ROWTYPE
AS $$
DECLARE
v_employee fgedu_employees%ROWTYPE;
BEGIN
SELECT * INTO v_employee FROM fgedu_employees WHERE id = p_id;
IF NOT FOUND THEN
RAISE EXCEPTION ‘Employee with ID % not found’, p_id;
END IF;
RETURN v_employee;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试函数
SELECT * FROM fgedu_get_employee_by_id(1);
— 输出结果
id | name | department | salary | hire_date
—-+——+————+———+————
1 | 张三 | 技术部 | 8000.00 | 2026-04-08
(1 row)
— 创建部门员工数量函数
CREATE OR REPLACE FUNCTION fgedu_get_employee_count_by_department(IN p_department VARCHAR(100))
RETURNS INTEGER
AS $$
DECLARE
v_count INTEGER;
BEGIN
SELECT COUNT(*) INTO v_count FROM fgedu_employees WHERE department = p_department;
RETURN v_count;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试函数
SELECT fgedu_get_employee_count_by_department(‘技术部’);
— 输出结果
fgedu_get_employee_count_by_department
—————————————-
2
(1 row)
SELECT fgedu_get_employee_count_by_department(‘销售部’);
— 输出结果
fgedu_get_employee_count_by_department
—————————————-
1
(1 row)
— 创建员工薪资统计函数
CREATE OR REPLACE FUNCTION fgedu_get_salary_stats()
RETURNS TABLE(
department VARCHAR(100),
employee_count INTEGER,
avg_salary NUMERIC(10,2),
min_salary NUMERIC(10,2),
max_salary NUMERIC(10,2)
)
AS $$
BEGIN
RETURN QUERY
SELECT
department,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary,
MIN(salary) AS min_salary,
MAX(salary) AS max_salary
FROM fgedu_employees
GROUP BY department
ORDER BY department;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试函数
SELECT * FROM fgedu_get_salary_stats();
— 输出结果
department | employee_count | avg_salary | min_salary | max_salary
————+—————-+————+————+————
技术部 | 2 | 8500.00 | 8000.00 | 9000.00
销售部 | 1 | 6000.00 | 6000.00 | 6000.00
(2 rows)
4.2 PostgreSQL数据库PL/pgSQL高级实战
本案例演示PL/pgSQL的高级使用,包括游标和动态SQL。更多学习教程公众号风哥教程itpux_com。
— 创建游标示例函数
CREATE OR REPLACE FUNCTION fgedu_test_cursor(IN p_department VARCHAR(100))
RETURNS TEXT
AS $$
DECLARE
cur_employees REFCURSOR;
v_employee fgedu_employees%ROWTYPE;
v_result TEXT := ”;
BEGIN
— 打开游标
OPEN cur_employees FOR
SELECT * FROM fgedu_employees WHERE department = p_department;
— 遍历游标
LOOP
FETCH cur_employees INTO v_employee;
EXIT WHEN NOT FOUND;
v_result := v_result || v_employee.name || ‘ (‘ || v_employee.salary || ‘), ‘;
END LOOP;
— 关闭游标
CLOSE cur_employees;
— 处理结果
IF v_result = ” THEN
RETURN ‘No employees found in ‘ || p_department;
ELSE
v_result := rtrim(v_result, ‘, ‘);
RETURN ‘Employees in ‘ || p_department || ‘: ‘ || v_result;
END IF;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试游标函数
SELECT fgedu_test_cursor(‘技术部’);
— 输出结果
fgedu_test_cursor
——————————
Employees in 技术部: 张三 (8000.00), 王五 (9000.00)
(1 row)
— 创建动态SQL函数
CREATE OR REPLACE FUNCTION fgedu_test_dynamic_sql(IN p_table_name TEXT, IN p_column_name TEXT, IN p_value TEXT)
RETURNS INTEGER
AS $$
DECLARE
v_sql TEXT;
v_count INTEGER;
BEGIN
— 构建动态SQL
v_sql := ‘SELECT COUNT(*) FROM ‘ || quote_ident(p_table_name) ||
‘ WHERE ‘ || quote_ident(p_column_name) || ‘ = $1’;
— 执行动态SQL
EXECUTE v_sql INTO v_count USING p_value;
RETURN v_count;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试动态SQL函数
SELECT fgedu_test_dynamic_sql(‘fgedu_employees’, ‘department’, ‘技术部’);
— 输出结果
fgedu_test_dynamic_sql
————————
2
(1 row)
— 创建批量插入函数
CREATE OR REPLACE FUNCTION fgedu_batch_insert_employees(IN p_employees JSONB)
RETURNS INTEGER
AS $$
DECLARE
v_employee JSONB;
v_count INTEGER := 0;
BEGIN
— 遍历JSON数组
FOR v_employee IN SELECT * FROM jsonb_array_elements(p_employees) LOOP
INSERT INTO fgedu_employees(name, department, salary)
VALUES(
v_employee->>’name’,
v_employee->>’department’,
(v_employee->>’salary’)::NUMERIC(10,2)
);
v_count := v_count + 1;
END LOOP;
RETURN v_count;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试批量插入函数
SELECT fgedu_batch_insert_employees(‘[{
“name”: “赵六”,
“department”: “财务部”,
“salary”: “7000.00”
}, {
“name”: “孙七”,
“department”: “销售部”,
“salary”: “6500.00”
}]’);
— 输出结果
fgedu_batch_insert_employees
——————————
2
(1 row)
— 查看插入结果
SELECT * FROM fgedu_employees;
— 输出结果
id | name | department | salary | hire_date
—-+——+————+———+————
1 | 张三 | 技术部 | 8000.00 | 2026-04-08
2 | 李四 | 销售部 | 6000.00 | 2026-04-08
3 | 王五 | 技术部 | 9000.00 | 2026-04-08
4 | 赵六 | 财务部 | 7000.00 | 2026-04-08
5 | 孙七 | 销售部 | 6500.00 | 2026-04-08
(5 rows)
4.3 PostgreSQL数据库PL/pgSQL复杂场景实战
本案例演示PL/pgSQL在复杂场景中的应用,包括业务逻辑处理。from PostgreSQL视频:www.itpux.com。
— 创建订单处理函数
CREATE OR REPLACE FUNCTION fgedu_process_order(
IN p_customer_id INTEGER,
IN p_items JSONB
)
RETURNS INTEGER
AS $$
DECLARE
v_order_id INTEGER;
v_item JSONB;
v_product_id INTEGER;
v_quantity INTEGER;
v_price NUMERIC(10,2);
v_total_amount NUMERIC(10,2) := 0;
BEGIN
— 开始事务
BEGIN
— 创建订单
INSERT INTO fgedu_orders(customer_id, total_amount, status)
VALUES(p_customer_id, 0, ‘pending’)
RETURNING id INTO v_order_id;
— 处理订单详情
FOR v_item IN SELECT * FROM jsonb_array_elements(p_items) LOOP
v_product_id := (v_item->>’product_id’)::INTEGER;
v_quantity := (v_item->>’quantity’)::INTEGER;
v_price := (v_item->>’price’)::NUMERIC(10,2);
— 插入订单详情
INSERT INTO fgedu_order_items(order_id, product_id, quantity, price)
VALUES(v_order_id, v_product_id, v_quantity, v_price);
— 计算总金额
v_total_amount := v_total_amount + (v_quantity * v_price);
END LOOP;
— 更新订单总金额
UPDATE fgedu_orders
SET total_amount = v_total_amount
WHERE id = v_order_id;
— 提交事务
RETURN v_order_id;
EXCEPTION
WHEN OTHERS THEN
— 回滚事务
RAISE EXCEPTION ‘Error processing order: %’, SQLERRM;
END;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 创建订单表和订单详情表
CREATE TABLE fgedu_orders (
id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL,
total_amount NUMERIC(10,2) NOT NULL,
status VARCHAR(20) DEFAULT ‘pending’,
created_at TIMESTAMP DEFAULT NOW()
);
— 输出结果
CREATE TABLE
CREATE TABLE fgedu_order_items (
id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES fgedu_orders(id),
product_id INTEGER NOT NULL,
quantity INTEGER NOT NULL,
price NUMERIC(10,2) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
— 输出结果
CREATE TABLE
— 创建客户表
CREATE TABLE fgedu_customers (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
— 输出结果
CREATE TABLE
— 插入客户数据
INSERT INTO fgedu_customers(name, email)
VALUES(‘张三’, ‘zhangsan@fgedu.net.cn’),
(‘李四’, ‘lisi@fgedu.net.cn’);
— 输出结果
INSERT 0 2
— 测试订单处理函数
SELECT fgedu_process_order(1, ‘[{
“product_id”: 1,
“quantity”: 2,
“price”: 7999.00
}, {
“product_id”: 2,
“quantity”: 1,
“price”: 4999.00
}]’);
— 输出结果
fgedu_process_order
——————–
1
(1 row)
— 查看订单
SELECT * FROM fgedu_orders;
— 输出结果
id | customer_id | total_amount | status | created_at
—-+————-+————–+———+—————————-
1 | 1 | 20997.00| pending | 2026-04-08 01:00:00
(1 row)
— 查看订单详情
SELECT * FROM fgedu_order_items;
— 输出结果
id | order_id | product_id | quantity | price | created_at
—-+———-+————+———-+——–+—————————-
1 | 1 | 1 | 2 | 7999.00| 2026-04-08 01:00:00
2 | 1 | 2 | 1 | 4999.00| 2026-04-08 01:00:00
(2 rows)
— 创建库存管理函数
CREATE OR REPLACE FUNCTION fgedu_update_inventory(
IN p_order_id INTEGER
)
RETURNS BOOLEAN
AS $$
DECLARE
v_item RECORD;
BEGIN
— 开始事务
BEGIN
— 遍历订单详情
FOR v_item IN
SELECT product_id, quantity FROM fgedu_order_items WHERE order_id = p_order_id
LOOP
— 更新库存(假设存在产品表)
— UPDATE fgedu_products SET stock = stock – v_item.quantity WHERE id = v_item.product_id;
— 模拟库存更新
RAISE NOTICE ‘Updating inventory for product %: quantity %’, v_item.product_id, v_item.quantity;
END LOOP;
— 更新订单状态
UPDATE fgedu_orders SET status = ‘completed’ WHERE id = p_order_id;
— 提交事务
RETURN TRUE;
EXCEPTION
WHEN OTHERS THEN
— 回滚事务
RAISE EXCEPTION ‘Error updating inventory: %’, SQLERRM;
RETURN FALSE;
END;
END;
$$ LANGUAGE plpgsql;
— 输出结果
CREATE FUNCTION
— 测试库存管理函数
SELECT fgedu_update_inventory(1);
— 输出结果
NOTICE: Updating inventory for product 1: quantity 2
NOTICE: Updating inventory for product 2: quantity 1
fgedu_update_inventory
————————
t
(1 row)
— 查看订单状态
SELECT id, customer_id, total_amount, status FROM fgedu_orders WHERE id = 1;
— 输出结果
id | customer_id | total_amount | status
—-+————-+————–+———-
1 | 1 | 20997.00| completed
(1 row)
Part05-风哥经验总结与分享
5.1 PostgreSQL数据库PL/pgSQL最佳实践
最佳实践:
- 代码组织:保持函数逻辑清晰,使用适当的缩进和注释
- 变量命名:使用有意义的变量名,遵循命名规范
- 错误处理:添加适当的异常处理机制
- 性能优化:避免不必要的计算和查询
- 安全性:使用参数化查询,避免SQL注入
- 测试:充分测试函数的各种场景
- 文档:为函数添加注释和文档
- 使用适当的变量类型,避免类型转换
- 使用批量操作,减少数据库交互
- 合理使用游标,避免内存溢出
- 使用动态SQL时注意安全
- 定期监控函数执行性能
- 使用版本控制管理函数代码
5.2 PostgreSQL数据库PL/pgSQL常见问题
常见问题:
- 性能问题:函数执行效率低下
- 内存问题:游标或变量占用过多内存
- 错误处理:异常处理不完善
- 安全问题:存在SQL注入风险
- 维护问题:函数代码难以维护
- 兼容性问题:不同PostgreSQL版本的语法差异
5.3 PostgreSQL数据库PL/pgSQL故障排查
故障排查:
- 性能问题:使用EXPLAIN分析函数执行计划
- 内存问题:检查游标使用和变量大小
- 错误处理:查看PostgreSQL日志,分析错误信息
- 安全问题:检查SQL注入风险
- 维护问题:重构函数代码,提高可读性
- 兼容性问题:检查PostgreSQL版本,确保语法兼容
— 查看函数执行情况
SELECT
proname AS function_name,
proargtypes::regtype[] AS arguments,
prorettype::regtype AS return_type,
prosrc AS source_code
FROM pg_proc
WHERE proname LIKE ‘fgedu%’;
— 输出结果
function_name | arguments | return_type | prosrc
————————–+————————-+—————————+—————————————————————————————————————————————————————–
fgedu_test_variables | {} | text |
DECLARE
— 标量变量
v_id INTEGER := 1;
v_name VARCHAR(100) := ‘张三’;
v_salary NUMERIC(10,2) := 8000.00;
v_active BOOLEAN := TRUE;
v_hire_date DATE := CURRENT_DATE;
— 复合变量
v_employee RECORD;
v_employee_row fgedu_employees%ROWTYPE;
— 数组变量
v_names TEXT[] := ARRAY[‘张三’, ‘李四’, ‘王五’];
v_salaries NUMERIC(10,2)[] := ARRAY[8000.00, 6000.00, 9000.00];
— 游标变量
cur_employees REFCURSOR;
BEGIN
— 变量赋值
v_name := ‘赵六’;
v_salary := v_salary + 1000.00;
— 使用变量
RAISE NOTICE ‘Employee ID: %’, v_id;
RAISE NOTICE ‘Employee Name: %’, v_name;
RAISE NOTICE ‘Employee Salary: %’, v_salary;
RAISE NOTICE ‘Active: %’, v_active;
RAISE NOTICE ‘Hire Date: %’, v_hire_date;
— 访问数组元素
RAISE NOTICE ‘First name: %’, v_names[1];
RAISE NOTICE ‘Second salary: %’, v_salaries[2];
— 获取行数据
SELECT * INTO v_employee_row FROM fgedu_employees WHERE id = v_id;
RAISE NOTICE ‘Employee from row: %, %’, v_employee_row.name, v_employee_row.department;
— 获取记录数据
SELECT id, name, department INTO v_employee FROM fgedu_employees WHERE id = v_id;
RAISE NOTICE ‘Employee from record: %, %’, v_employee.name, v_employee.department;
RETURN ‘Variables test completed’;
END;
— 查看函数依赖
SELECT
p.proname AS function_name,
d.refobjid::regclass AS dependency
FROM pg_proc p
JOIN pg_depend d ON d.objid = p.oid
WHERE p.proname LIKE ‘fgedu%’
AND d.refclassid = ‘pg_class’::regclass;
— 输出结果
function_name | dependency
————————–+——————-
fgedu_get_employee_by_id | fgedu_employees
fgedu_test_variables | fgedu_employees
fgedu_batch_insert_employees | fgedu_employees
fgedu_get_employee_count_by_department | fgedu_employees
fgedu_get_salary_stats | fgedu_employees
fgedu_test_cursor | fgedu_employees
fgedu_process_order | fgedu_orders
fgedu_process_order | fgedu_order_items
fgedu_update_inventory | fgedu_orders
fgedu_update_inventory | fgedu_order_items
(10 rows)
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
