SQL 存储过程:从硬编码逻辑到可重用的 SQL
Source: Dev.to
什么终于让人恍然大悟:存储过程只是可复用的逻辑
我一开始犯的错误是把存储过程当成了什么高深的东西。
它们并不是。
存储过程不过是一个有名字的 SQL 逻辑,存放在数据库里并且可以接受输入。仅此而已。
如果你已经了解:
- 函数
- 参数
- if / else 逻辑
那么存储过程并不是一个全新的概念,只是一个在新环境中的新名称。
为什么普通 SQL 开始显得受限
想象一下这个非常普通的需求:
“给我所有金额超过某个数值的订单。”
在普通 SQL 中,我可能会写:
select *
from orders
where total_amount > 1000;
这样可以工作……但它是 硬编码 的。
如果规则改成 1500,我必须修改查询。
如果另一个报表需要 500,我就复制这段查询。
这种重复正是存储过程开始有意义的地方。
我的第一个有用的存储过程
create or replace procedure high_value_orders
as
begin
select *
from orders
where total_amount > 1000;
end;
现在我只需要执行:
exec high_value_orders;
逻辑可以工作,但规则仍然是硬编码的。
真正的升级:参数
不要在过程内部固定数值,而是把它作为参数传入:
create or replace procedure high_value_orders (
p_min_amount number
)
as
begin
select *
from orders
where total_amount > p_min_amount;
end;
现在我可以用不同的阈值复用同一逻辑:
exec high_value_orders(500);
exec high_value_orders(1500);
这使得过程变成了可配置的行为。
CASE 出场的时刻
一开始 CASE 让我感到困惑,因为我总是看到它的抽象解释。
把它用于编码业务规则后就明白了。
示例需求: “根据客户的消费金额对其进行分类。”
select
customer_id,
total_spent,
case
when total_spent >= 5000 then 'VIP'
when total_spent >= 2000 then 'Regular'
else 'Occasional'
end as customer_type
from customers;
CASE 是 SQL 版的 if / else——从上到下依次评估条件。
将 CASE 与存储过程结合
假设业务想要:
“显示客户,但根据我关心的阈值给他们贴不同的标签。”
create or replace procedure customer_segments (
p_vip_threshold number
)
as
begin
select
customer_id,
total_spent,
case
when total_spent >= p_vip_threshold then 'VIP'
else 'Non-VIP'
end as segment
from customers;
end;
现在逻辑可以适配:
exec customer_segments(5000);
exec customer_segments(3000);
同一个过程,不同的行为。
我之前的错误做法
- 把存储过程当成高级 SQL 语法
- 回避参数,所有东西都硬编码
- 把 CASE 当成技巧,而不是逻辑
把它们重新定义为:
- 可复用的逻辑
- 可配置的输入
- 条件规则
一切就恍然大悟了。
为什么这超越了语法层面
SQL 不仅仅是查询数据;它还可以:
- 强制执行规则
- 集中管理逻辑
- 减少重复
- 使行为显式化
存储过程并不总是答案,但理解它们会改变你对数据库的思考方式。
结语
如果你曾觉得存储过程或 CASE 过于沉重或不必要,我能理解。
它们只有在你不再思考:
“我该怎么写这个查询?”
而开始思考:
“我该怎么让这段逻辑可复用?”
这种转变我花了一段时间才实现,但一旦实现,SQL 就不再显得浅薄。