Why use it ?
我们为什么要使用存储过程?
存储过程的优缺点
♛ 优点
❄ 执行快
存储过程在执行时是会被SQL优化缓存的,而SQL语句则没有。存储过程比直接写SQL语句执行起来的速度快。
❄ 易修改
存储过程修改比较快和方便,如果是在编写程序时,只是通过存储过程的名来调用存储过程,一个程序可能在多个地方被引用,所以也可以简化程序。在修改时也比较方便,不用一句一句的去修改。
❄ 增强安全性
a、通过向用户授予对存储过程(而不是基于表)的访问权限,它们可以提供对特定数据的访问;
b、提高代码安全,防止 SQL注入(但未彻底解决,例如,将数据操作语言--DML,附加到输入参数);
c、SqlParameter 类指定存储过程参数的数据类型,作为深层次防御性策略的一部分,可以验证用户提供的值类型(但也不是万无一失,还是应该传递至数据库前得到附加验证)。
➼ 缺点
☏ 使用操作有范围
如果更改范围大到需要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则您仍需要更新程序集中的代码以添加参数、更新 GetValue() 调用,等等,这时候估计比较繁琐了。
☏ 可移植性差
由于存储过程将应用程序绑定到 SQL Server,因此使用存储过程封装业务逻辑将限制应用程序的可移植性。如果应用程序的可移植性在您的环境中非常重要,则将业务逻辑封装在不特定于 RDBMS 的中间层中可能是一个更佳的选择。
☏ 不支持OO
大量采用存储过程进行业务逻辑的开发致命的缺点是很多存储过程不支持面向对象的设计,无法采用面向对象的方式将业务逻辑进行封装,从而无法形成通用的可支持复用的业务逻辑框架。
☏ 难维护
代码可读性差,相当难维护.
How to use it ?
怎么使用?
仍给你一个例子。
♒
现在我就来总结一下C#使用SQL存储过程完整的流程,以SQL2005为例。
先简单的说说什么是存储过程:存储过程就是固化在SQL数据库系统内部的SQL语句,这样做的好处是可以提高执行效率、提高数据库的安全性、减少网络流量。接下来就讲解如何在数据库中建立一个存储过程。
打开SQL2055数据库,展开“数据库”节点,找到你使用的数据库(目的数据库),展开该数据库节点,找到“可编程性”节点并展开,就可以看到“存储过程”了,在“存储过程”上点击右键,新建存储过程。然后会弹出查询分析器,在这输入创建代码就可以了。
代码如下:
-
create proc myproc
-- 创建一个存储过程,名称为myproc
-
--这里写参数,如果有的话;没有的话就空着
-
as
-
--这里写具体语句,可以写N个
-
go
--可加可不加,go的意思是另起一页,相当于下一个功能块。如果下边不写语句,可以不加!
例如:
-
create proc myproc
-
@username
varchar(
10),
--注意这里的逗号,多个参数用逗号隔开
-
@
password
varchar(
10),
-
@
name
varchar(
10),
-
@usertype
varchar(
10),
-
@createpeople
varchar(
10)
-
as
-
insert
into SystemUsers(UserName,
PassWord,
Name,UserType,CreatPeople)
values(@username,@
password,@
name,@usertype,@createpeople)
-
go
这个存储过程可以向SystemUsers表中插入一条记录。
以上讲的是手动建立存储过程的方法,其实完全不必这么麻烦,直接点击SQL2005左上角的“新建查询”,打开查询分析器,然后在上边的语句中加入一句话:“use JF_Charging_System”意思就是使用某个数据库,也就是在哪个数据库中建立存储过程。
例如:
-
use JF_Charging_System
-
go
-
create proc myproc
-
@username
varchar(
10),
-
@
password
varchar(
10),
-
@
name
varchar(
10),
-
@usertype
varchar(
10),
-
@createpeople
varchar(
10)
-
as
-
insert
into SystemUsers(UserName,
PassWord,
Name,UserType,CreatPeople)
values(@username,@
password,@
name,@usertype,@createpeople)
-
go
下面再来讲解如何在C#中调用存储过程。废话不过说,一段完整的代码+注释让你明白一切!这段C#代码和上边的存储过程是完全对应的。
-
string strsql =
"Data Source=192.168.24.53;Initial Catalog=JF_Charging_System;Persist Security Info=True;User ID=sa;Password=1";
//数据库链接字符串
-
string sql =
"myproc";
//要调用的存储过程名
-
SqlConnection conStr =
new SqlConnection(strsql);
//SQL数据库连接对象,以数据库链接字符串为参数
-
SqlCommand comStr =
new SqlCommand(sql, conStr);
//SQL语句执行对象,第一个参数是要执行的语句,第二个是数据库连接对象
-
comStr.CommandType = CommandType.StoredProcedure;
//因为要使用的是存储过程,所以设置执行类型为存储过程
-
//依次设定存储过程的参数
-
comStr.Parameters.Add(
"@username", SqlDbType.VarChar,
10).Value =
"11";
-
comStr.Parameters.Add(
"@password", SqlDbType.VarChar,
10).Value =
"11";
-
comStr.Parameters.Add(
"@name", SqlDbType.VarChar,
10).Value =
"11";
-
comStr.Parameters.Add(
"@usertype", SqlDbType.VarChar,
10).Value =
"11";
-
comStr.Parameters.Add(
"@createpeople", SqlDbType.VarChar,
10).Value =
"11";
-
conStr.Open();
//打开数据库连接
-
MessageBox.Show(comStr.ExecuteNonQuery().ToString());
//执行存储过程
-
conStr.Close();
//关闭连接
希望对大家有所帮助!
如何调用
除了上面的例子中的调用还有同类调用
同类调用:
在存储过程里用exec 执行另一存储过程名及它需要的参数就可以了
如 exec abc ‘1’, ‘2’(abc 是存储过程的名字, ‘1’,’2’ 是它的参数
TIPS:
学习小贴式
♪ @username
在SQL Server .NET数据提供程序中指定参数
SQL Server .NET数据提供程序支持指定的参数。
当命令文本在指定具体命令时,必须指出哪一部分是在运行时进行设置的,也就是必须指出哪部分是参数。
那些可变的部分即参数,它们都必须有一个@前缀。
Update student set sName=@userName where ID=@userid
这个命令中,@userName和@userid为参数,它们的值在运行时是可变的。
♪ cmd.ExecuteNonQuery()的用法
报错1:数据重复时,提示“防止插入重复键,语句终止错误”
解决:
这种情况一般在数据插入前判断数据表中是否有该数据。
修改方法有两种:
第一种是修改原来的process过程,在过程中插入数据前先判断有无数据,有数据则不插入;
第二种是修改程序,在执行process过程前,执行一次有无数据的查询,通过结果来判断是否运行process过程。
报错2:Connection 属性尚未初始化
解决:
没有给command对象指定相应参数
没把 SqlConnection 对象传给SqlCommand
介绍:ExecuteNonQuery方法主要用来更新数据。
通常使用它来执行Update、Insert和Delete语句。
该方法返回值意义如下:
对于Update、Insert和Delete语句,返回值为该命令所影响的行数。
对于所有其他类型的语句,返回值为-1。
Command对象通过ExecuteNonQuery方法更新数据库的过程非常简单,需要进行的步骤如下:
(1)创建数据库连接。
(2)创建Command对象,并指定一个SQL Insert、Update、Delete查询或存储过程。
(3)把Command对象依附到数据库连接上。
(4)调用ExecuteNonQuery方法。
(5)关闭连接。