做者:丶平凡世界数据库
来源: SQL数据库开发缓存
时不时有小伙伴私聊我这个存储过程怎么这么难啊?安全
说实话,我刚开始学SQL也以为写存储过程多是整个SQL开发中最难的了。由于存储过程简单起来能够只写一句SELECT就行,复杂起来写几天几夜也未必能写完(夸张了)。服务器
但也不是说学不会,今天就给你们好好恶补一下存储过程的一些常规用法,一些很是规用法实在是太多了,这里就不一一列举了。网络
建立存储过程并发
create proc | procedure procedure_name[{@参数数据类型} [=默认值] [output],性能
{@参数数据类型} [=默认值] [output],优化
....加密
]spa
as
SQL_statements
go
示例
create proc sp_test
@param1 int,
@param2 varchar(16)
as
select * from test
where id=@param1
and t_no=@param2;
go
上面就是一个简单的示例。
存储过程在建立阶段能够带参数或不带参数,不带参数的通常是执行一些不须要传递参数的语句就能够完成的功能,带参数那就是须要传递参数的SQL语句,就像上面的示例,传递了两个参数给SQL语句。带参数的必定要定义参数类型,是字符型的还要定义长度,给参数加默认值是可选的。
存储过程的优势和缺点
优势:
一、提升性能
SQL语句在建立过程时进行分析和编译。存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的存储计划,这样,在执行过程时即可节省此开销。
二、下降网络开销
存储过程调用时只需用提供存储过程名和必要的参数信息,从而可下降网络的流量。
三、便于进行代码移植
数据库专业人员能够随时对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的提升了程序的可移植性。
四、更强的安全性
1)系统管理员能够对执行的某一个存储过程进行权限限制,避免非受权用户对数据的访问
2)在经过网络调用过程时,只有对执行过程的调用是可见的。所以,恶意用户没法看到表和数据库对象名称、嵌入本身的 Transact-SQL 语句或搜索关键数据。
3)使用过程参数有助于避免 SQL 注入攻击。由于参数输入被视做文字值而非可执行代码,因此,攻击者将命令插入过程内的 Transact-SQL 语句并损害安全性将更为困难。
4)能够对过程进行加密,这有助于对源代码进行模糊处理。
劣势:
一、逻辑处理吃力
SQL自己是一种结构化查询语言,但不是面向对象的的,本质上仍是过程化的语言,面对复杂的业务逻辑,过程化的处理会很吃力。同时SQL擅长的是数据查询而非业务逻辑的处理,若是若是把业务逻辑全放在存储过程里面,违背了这一原则。
二、修改参数复杂
若是须要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则您仍须要更新程序集中的代码以添加参数、更新调用,等等,这时候估计会比较繁琐了。
三、开发调试复杂
因为IDE的问题,存储过程的开发调试要比通常程序困难。
四、没法应用缓存
虽然有全局临时表之类的方法能够作缓存,但一样加剧了数据库的负担。若是缓存并发严重,常常要加锁,那效率实在堪忧。
五、不支持群集
数据库服务器没法水平扩展,或者数据库的切割(水平或垂直切割)。数据库切割以后,存储过程并不清楚数据存储在哪一个数据库中。
存储过程的具体应用
基础应用
一、建立不带参数的存储过程
示例:查询订单表中订单总数
--查询存储过程
IF OBJECT_ID (N'PROC_ORDER_COUNT', N'P') IS NOT NULL
DROP procedure PROC_ORDER_COUNT;
GO
CREATE procedure PROC_ORDER_COUNT
AS
SELECT COUNT(OrderID) FROM Orders;
GO
--执行上述存储过程:
EXEC PROC_ORDER_COUNT;
二、建立带参数的存储过程
示例:根据城市查询订单数量
--查询存储过程,根据城市查询总数
IF OBJECT_ID (N'PROC_ORDER_COUNT', N'P') IS NOT NULL
DROP procedure PROC_ORDER_COUNT;
GO
CREATE procedure PROC_ORDER_COUNT(@city nvarchar(50))
AS
SELECT COUNT(OrderID) FROM Orders WHERE City=@city
GO
--执行上述存储过程:
EXEC PROC_ORDER_COUNT N'GuangZhou';
进阶应用
三、参数带通配符
--查询订单编号头两位是LJ的订单信息,含通配符
IF OBJECT_ID (N'PROC_ORDER_INFO', N'P') IS NOT NULL
DROP procedure PROC_ORDER_INFO;
GO
CREATE procedure PROC_ORDER_INFO
@OrderID nvarchar(50)='LJ%' --默认值
AS
SELECT OrderID,City,OrderDate,Price FROM Orders
WHERE OrderID like @OrderID;
GO
--执行上述存储过程:
EXEC PROC_ORDER_INFO;
EXEC PROC_ORDER_INFO N'LJ%';
EXEC PROC_ORDER_INFO N'%LJ%';
四、带输出参数
--根据订单查询的信息,返回订单的城市及单价
IF OBJECT_ID (N'PROC_ORDER_INFO ', N'P') IS NOT NULL
DROP procedure PROC_ORDER_INFO ;
GO
CREATE procedure PROC_ORDER_INFO
@orderid nvarchar(50), --输入参数
@city nvarchar(20) out, --输出参数
@price float output --输入输出参数
AS
SELECT @city=City,@price=Price FROM Orders
WHERE OrderID=@orderid AND Price=@price;
GO
--执行上述存储过程:
declare @orderid nvarchar(50),
@city nvarchar(20),
@price int;
set @orderid= N'LJ0001';
set @price = 35.21;
exec PROC_ORDER_INFO @orderid,@city out, @price output;
select @city, @price;
上面两个在平时工做中遇到的较少,须要的时候知道怎么用便可,1,2个是必须掌握的操做。
存储过程进行增删改
一、新增
--新增订单信息
IF OBJECT_ID (N'PROC_INSERT_ORDER', N'P') IS NOT NULL
DROP procedure PROC_INSERT_ORDER;
GO
CREATE procedure PROC_INSERT_ORDER
@orderid nvarchar(50),
@city nvarchar(20),
@price float
AS
INSERT INTO Orders(OrderID,City,Price)
VALUES(@orderid,@city,@price)
GO
--执行
EXEC PROC_INSERT_ORDER N'LJ0001',N'GuangZhou',35.21;
二、修改
--修改订单信息
IF OBJECT_ID (N'PROC_UPDATE_ORDER', N'P') IS NOT NULL
DROP procedure PROC_UPDATE_ORDER;
GO
CREATE procedure PROC_UPDATE_ORDER
@orderid nvarchar(50),
@city nvarchar(20),
@price float
AS
UPDATE Orders SET OrderID=@orderid,City=@city,Price=@price;
GO
--执行
EXEC PROC_UPDATE_ORDER N'LJ0001',N'ShangHai',37.21;
三、删除
--修改订单信息
IF OBJECT_ID (N'PROC_DELETE_ORDER', N'P') IS NOT NULL
DROP procedure PROC_DELETE_ORDER;
GO
CREATE procedure PROC_DELETE_ORDER
@orderid nvarchar(50),
AS
DELETE FROM Orders WHERE OrderID=@orderid;
GO
--执行
EXEC PROC_DELETE_ORDER N'LJ0001';
存储过程其余功能
这部分是选修内容,有兴趣的能够了解一下
一、重复编译存储过程
--重复编译
IF OBJECT_ID (N'PROC_ORDER_WITH_RECOMPILE', N'P') IS NOT NULL
DROP procedure PROC_ORDER_WITH_RECOMPILE;
GO
CREATE procedure PROC_ORDER_WITH_RECOMPILE
with recompile --重复编译
AS
SELECT * FROM Orders;
GO
二、加密存储过程
--查询存储过程,进行加密,加密后不能查看和修改源脚本
IF OBJECT_ID (N'PROC_ORDER_WITH_ENCRYPTION', N'P') IS NOT NULL
DROP procedure PROC_ORDER_WITH_ENCRYPTION;
GO
CREATE procedure PROC_ORDER_WITH_ENCRYPTION
with encryption --加密
AS
SELECT * FROM Orders;
GO
--执行上述存储过程:
EXEC PROC_ORDER_WITH_ENCRYPTION
执行完的效果如图:
以上就是存储过程的详细用法了。还有不明白或有疑问的地方,欢迎留言讨论。