1、在大型数据库系统中,一组为了完成特定功能的SQL语句集,存储在数据库中(就像我们C#当中封装的方法一样,可以重复调用)经过第一次编译后再次调用不需要再次编译,用户指定存储过程的名字并给出参数(如果该存储过程带有参数的话)来执行它。
2、存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数、输出参数、返回单个或多个结果集以及返回值。
①重复使用。存储过程可以重复使用,从而可以减少数据库开发人员的工作量。
②减少网络流量。存储过程位于服务器上,调用的时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输的数据量。
③安全性。参数化的存储过程可以防止SQL注入式攻击,而且可以将Grant、Deny以及Revoke权限应用于存储过程。
简单讲:
1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2.当对数据库进行复杂操作时(如对多个表进行Update,Insert,Query,Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用.
3.存储过程可以重复使用,可减少数据库开发人员的工作量
4.安全性高,可设定只有某些用户才具有对指定存储过程的使用权
1:调试麻烦,但是用 PL/SQL Developer 调试很方便!弥补这个缺点。
2:移植问题,数据库端代码当然是与数据库相关的。但是如果是做工程型项目,基本不存在移植问题。
3:重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。
4: 维护麻烦,如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。
Create procedure sp_name
@[参数名][参数名]@[参数名][类型]
As
Begin
……
End
//注意:sp_name 为需要创建的存储过程的名字,该名字不可以以阿拉伯数字开头
Exec sp_name[参数名]
Drop procedure sp_name
//不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程
我们在机房合作中,三个组合查询就用到了存储过程,因为三个组合查询的SQL语句基本一样,所以我们将它封装在了数据库中的特定存储过程中,需要的时候直接在DAL层调用即可。
用户基本信息查询的D层代码
public List GroupFindTemplateCard(Entity.GroupFindTemplate groupfind)
{
//为存储过程中需要的参数赋值
SqlParameter[] sqlparameter =
{
new SqlParameter ("@comboOperators1", groupfind .CmbCondition1 ),
new SqlParameter ("@comboOperators2", groupfind .CmbCondition2 ),
new SqlParameter ("@comboOperators3",groupfind .CmbCondition3 ),
new SqlParameter ("@comboFields1", groupfind.CmbParameter1 ),
new SqlParameter ("@comboFields2",groupfind .CmbParameter2 ),
new SqlParameter ("@comboFields3",groupfind .CmbParameter3 ),
new SqlParameter ("@comboCheck1",groupfind .CmbRelationship1 ),
new SqlParameter ("@comboCheck2",groupfind .CmbRelationship2 ),
new SqlParameter ("@textBox1",groupfind .textBox1 ),
new SqlParameter ("@textBox2",groupfind .textBox2 ),
new SqlParameter ("@textBox3",groupfind .textBox3 ),
new SqlParameter ("@DbName",groupfind .DbtableName )
};
//调用存储过程语句
string sql = @"JF_GroupCheck";//存储过程的名称
//执行sql操作
DataTable table = sqlhelper.ExecuteQuery(sql, sqlparameter, CommandType.StoredProcedure);
//datatable转泛型
List mylist = new List();
CovertListHelper coverlisthelper = new CovertListHelper();
mylist = coverlisthelper.covertToList(table);
return mylist;
}
数据库中的存储过程
-- =============================================
-- Author: ZHY
-- Create date: 2018-12-7
-- Description: 组合查询存储过程
-- =============================================
ALTER PROCEDURE [dbo].[JF_GroupCheck] --定义存储过程的名称
@DbName nvarchar(50), --执行sql语句所需要的参数
@comboFields1 nvarchar(20),
@comboFields2 nvarchar(20),
@comboFields3 nvarchar(20),
@comboOperators1 nvarchar(10),
@comboOperators2 nvarchar(10),
@comboOperators3 nvarchar(10),
@textBox1 nvarchar(20),
@textBox2 nvarchar(20),
@textBox3 nvarchar(20),
@comboCheck1 nvarchar(10),
@comboCheck2 nvarchar(10)
AS
declare @TempSql varchar(500)--临时存放sql语句
--Char(32)是空格 插入(39)是单引号
BEGIN
--一个条件的查询
SET @TempSql=' select * from '+@DbName+' where '+char(32)+@comboFields1+@comboOperators1+char(39)+@textBox1+char(39)
if(@comboCheck1 ='and' or @comboCheck1='or')
begin
--两个条件的查询
SET @TempSql=@TempSql+char(32)+@comboCheck1+char(32)+@comboFields2+@comboOperators2+char(39)+@textBox2+char(39)
if(@comboCheck2 ='and' or @comboCheck2='or')
begin
--三个条件的查询
SET @TempSql=@TempSql+char(32)+@comboCheck2+char(32)+@comboFields3+@comboOperators3+char(39)+@textBox3+char(39)
end
end
execute(@Tempsql)
END