存储过程其实就是已预编译为可执行过程的一个或多个SQL语句。 通过调用和传递参数即可完成该存储过程的功能。
前面有介绍过存储过程的一些语法,但是没有详细示例,今天我们来一起研究一下存储过程。
一、创建存储过程语法
create proc | procedure procedure_name [{@参数数据类型} [=默认值] [output], {@参数数据类型} [=默认值] [output], .... ]as SQL_statementsgo
示例
create proc sp_test @param1 int, @param2 varchar(16) as select * from test where id=@param1 and t_no=@param2; go
上面就是一个简单的示例。
存储过程在创建阶段可以带参数或不带参数,不带参数的一般是执行一些不需要传递参数的语句就可以完成的功能,带参数那就是需要传递参数的SQL语句,就像上面的示例,传递了两个参数给SQL语句。带参数的一定要定义参数类型,是字符型的还要定义长度,给参数加默认值是可选的。
二、存储过程的优点和缺点
优点:
1提高性能
SQL语句在创建过程时进行分析和编译。 存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的存储计划,这样,在执行过程时便可节省此开销。
2降低网络开销
存储过程调用时只需用提供存储过程名和必要的参数信息,从而可降低网络的流量。
3便于进行代码移植
数据库专业人员可以随时对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的提高了程序的可移植性。
4更强的安全性
1)系统管理员可以对执行的某一个存储过程进行权限限制,避免非授权用户对数据的访问
2)在通过网络调用过程时,只有对执行过程的调用是可见的。 因此,恶意用户无法看到表和数据库对象名称、嵌入自己的 Transact-SQL 语句或搜索关键数据。
3)使用过程参数有助于避免 SQL 注入攻击。 因为参数输入被视作文字值而非可执行代码,所以,攻击者将命令插入过程内的 Transact-SQL 语句并损害安全性将更为困难。
4)可以对过程进行加密,这有助于对源代码进行模糊处理。
劣势:
1逻辑处理吃力
SQL本身是一种结构化查询语言,但不是面向对象的的,本质上还是过程化的语言,面对复杂的业务逻辑,过程化的处理会很吃力。同时SQL擅长的是数据查询而非业务逻辑的处理,如果如果把业务逻辑全放在存储过程里面,违背了这一原则。
2修改参数复杂
如果需要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则您仍需要更新程序集中的代码以添加参数、更新调用,等等,这时候估计会比较繁琐了。
3开发调试复杂
由于IDE的问题,存储过程的开发调试要比一般程序困难。
4无法应用缓存
虽然有全局临时表之类的方法可以做缓存,但同样加重了数据库的负担。如果缓存并发严重,经常要加锁,那效率实在堪忧。
5不支持群集
数据库服务器无法水平扩展,或者数据库的切割(水平或垂直切割)。数据库切割之后,存储过程并不清楚数据存储在哪个数据库中。
三、具体应用
基础应用
1创建不带参数的存储过程
示例:查询订单表中订单总数
--查询存储过程 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;
2创建带参数的存储过程
示例:根据城市查询订单数量
--查询存储过程,根据城市查询总数 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';
进阶应用
3参数带通配符
--查询订单编号头两位是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%';
4带输出参数
--根据订单查询的信息,返回订单的城市及单价 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个是必须掌握的操作。
四、存储过程进行增删改
1新增
--新增订单信息 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;
2修改
--修改订单信息
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;
3删除
--修改订单信息 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';
5其他功能
这部分是选修内容,有兴趣的可以了解一下
1重复编译存储过程
--重复编译 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
2加密存储过程
--查询存储过程,进行加密,加密后不能查看和修改源脚本 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
执行完的效果如图:
问:卡牌大师游戏闪退怎么解决?答:游戏闪退无非就是内存不足的问题,通常情况下,内存不足就会出现游戏闪退。这个时候将不用的程序清理掉,就可以玩了。当然也会出现因游戏文件包损坏,导致游戏闪退弹出。这种情况一般都是非法安装外挂和辅助造成的,所以建议大家不要用辅助等类型的第三方软件。以上就是常见的二种现象,
2024-11-22 10:29:28
炸麻叶儿是我们北方的传统特色小吃,小时候逢年过节、家家户户都会预备一些,焦香酥脆、越嚼越香,可是那时候最好的零食。现在生活条件好了,各式各样的零食应接不暇,眼看着这些传统的、经典的小吃逐渐淡出了大家的视野,着实觉得有些可惜。今天,我就把这款地道的、河南特有的、酥的直掉渣的炸麻叶做法,再给大家分享一遍
2024-11-22 09:35:04
最近发现,越来越多的人开始喜欢机械手表了。相比石英手表,机械手表虽然更贵,但是也更有质感和品味,也是不争的事实。相信很多越来越喜欢机械表的人都是认定了这个理儿。其实,我们常听说的一些大牌钟表,都是以机械手表见长,甚至有不少大牌手表都没有石英手表,比如朗格、宝玑等。论知名度和影响力,以下这些机械手表比
2024-11-22 09:19:48
用料青辣椒一根 红萝卜一根 生芒果一颗 盐渍话梅3粒切丝 日本话梅片6片切丝 备用 柠檬汁适量 矿泉水适量 少许盐 糖 太太乐鸡汁适量调一个咸鲜口 好了… 做法步骤1、买一个芒果准备学做牛肉芒果条菜的…2、切开一看 哇~生的 …3、只能改菜了 凉拌吧 红萝卜切丝 青椒切丝 盐渍话梅切丝(切出来成粒了
2024-11-22 09:04:05
传说东汉刘秀在未登大宝前有过一段很落魄的日子,亏得一位农村老汉割了一种野菜给刘秀充饥,刘秀吃后觉得甚是美味,便给野菜起了“救菜”的名字。此菜就是现在的韭菜,古语有云:“春初早韭,秋末晚菘”,意思是初春时刻,在经历过一个寒冬的缓慢生长后,是韭菜最为鲜嫩完美的一段时间,晚秋次之,夏天味道最差,所以各位碰
2024-11-22 08:49:26
今天来跟大家分享一个洋葱肉丸汤的做法,这样做出来的肉丸子非常好吃,比较鲜嫩,一点也不柴,爽滑可口,而且汤汁喝起来特别鲜美,光看着就让人特别有食欲,而且它的营养特别丰富。这道洋葱肉丸汤的做法是比较简单的,很容易就能够做出来,非常适合在夏天食用。如果家里有小朋友,那么经常给它吃这样的洋葱肉丸汤,可以起到
2024-11-22 08:34:03