2026/1/21 4:40:58
网站建设
项目流程
网站设计结构图用什么做,xampp用wordpress,旺旺食品有限公司网页设计,可口可乐网站建设策划方案在 PostgreSQL 里#xff0c;其实 99% 场景你写的是 函数#xff08;FUNCTION#xff09;#xff1b;真正的 存储过程#xff08;PROCEDURE#xff09; 是 11 版才引入#xff0c;语法几乎一样#xff0c;只是调用方式不同。下面把“函数”和“过程”都给你一次讲透其实 99% 场景你写的是 函数FUNCTION真正的 存储过程PROCEDURE 是 11 版才引入语法几乎一样只是调用方式不同。下面把“函数”和“过程”都给你一次讲透并附完整可直接 psql -f 运行的脚本。---一、先分清FUNCTION vs PROCEDURE特性 FUNCTION PROCEDURE最早版本 一直就有 ≥ 11能否回传结果集 ✅ RETURNS TABLE / SETOF ❌只能 OUT 参数调用方式 SELECT func(args); CALL proc(args);能否无返回值 ❌ 必须有 RETURNS ✅ 可以啥都不返回事务控制 由外层决定 内部可 COMMIT/ROLLBACK结论- 只要你想“查”数据 → 写 FUNCTION- 只要你想“干”事且内部自己提交 → 写 PROCEDURE。---二、FUNCTION 模板最常用sql-- 返回单行CREATE OR REPLACE FUNCTION get_user_name(uid bigint)RETURNS textLANGUAGE plpgsqlAS $$DECLAREv_name text;BEGINSELECT name INTO v_nameFROM usersWHERE id uid;RETURN v_name; -- 找不到会返回 NULLEND;$$;-- 返回结果集CREATE OR REPLACE FUNCTION list_users(min_age int)RETURNS TABLE(id bigint, name text, age int)LANGUAGE plpgsqlAS $$BEGINRETURN QUERYSELECT u.id, u.name, u.ageFROM users uWHERE u.age min_ageORDER BY u.age;END;$$;-- 测试SELECT get_user_name(1);SELECT * FROM list_users(18);---三、PROCEDURE 模板≥ pg11sql-- 内部自己提交外部自动回滚不了CREATE OR REPLACE PROCEDURE transfer_money(from_id bigint,to_id bigint,amount numeric)LANGUAGE plpgsqlAS $$BEGIN-- 扣钱UPDATE accounts SET balance balance - amount WHERE id from_id;-- 加钱UPDATE accounts SET balance balance amount WHERE id to_id;-- 记日志INSERT INTO log(from_acc, to_acc, amt, ts)VALUES (from_id, to_id, amount, now());-- 手动提交函数里不允许COMMIT;END;$$;-- 调用CALL transfer_money(3, 5, 100.00);---四、参数 5 种写法速查1. IN 默认只进不出2. OUT 只出不进3. INOUT 能进能出4. VARIADIC 可变长参数5. 缺省值 age int DEFAULT 18示例INOUTsqlCREATE OR REPLACE FUNCTION swap(INOUT a int, INOUT b int)LANGUAGE plpgsql AS $$DECLARE tmp int;BEGINtmp : a; a : b; b : tmp;END;$$;-- 调用SELECT swap(3,7); -- 返回 7,3---五、异常处理模板sqlCREATE OR REPLACE FUNCTION safe_divide(a numeric, b numeric)RETURNS numericLANGUAGE plpgsqlAS $$BEGINRETURN a / b;EXCEPTIONWHEN division_by_zero THENRAISE NOTICE 除零返回 NULL;RETURN NULL;WHEN OTHERS THENRAISE WARNING 未知错误: %, SQLERRM;RETURN NULL;END;$$;---六、快速验证脚本把下面内容存成 proc.sql然后psql -U postgres -d yourdb -f proc.sql 即可一键验证。sql-- 建测试表DROP TABLE IF EXISTS users;CREATE TABLE users(id bigserial PRIMARY KEY,name text NOT NULL,age int CHECK (age0));-- 灌点数据INSERT INTO users(name,age) VALUES(Alice,19),(Bob,25),(Carol,30);-- 函数返回结果集CREATE OR REPLACE FUNCTION list_users(min_age int)RETURNS TABLE(id bigint, name text, age int)LANGUAGE plpgsql AS $$BEGINRETURN QUERY SELECT u.id, u.name, u.age FROM users u WHERE u.age min_age;END;$$;-- 过程无结果内部可 COMMITCREATE OR REPLACE PROCEDURE add_user(p_name text, p_age int)LANGUAGE plpgsql AS $$BEGININSERT INTO users(name,age) VALUES (p_name, p_age);COMMIT;END;$$;-- 测试SELECT * FROM list_users(20); -- 函数CALL add_user(David, 40); -- 过程SELECT * FROM list_users(20);---七、小结口诀- 要查询 → FUNCTION RETURNS/TABLE- 要干活 → PROCEDURE CALL≥11- 想回传单个值 → OUT 参数- 想回传结果集 → RETURN QUERY