ADO.NET调用存储过程
使用存储过程
存储过程有两点优点:
- 性能高
- 安全性好
在ADO.NET中调用存储过程
SqlCommand cmd = new SqlCommand();
cmd.CommandText ="sp_update_student";
cmd.CommendType = CommandType.StoredProcedure;
//...定义和添加SqlParameter参数
//...打开链接并执行命令
其中CommandText是负责讲存储过程名成包装成字符串发送给数据库,但是数据库只是默认String为sql语句。会报错,所以要设置CommendType属性。
例子上文将CommendType定义为: StoredProcedure,也就是存储过程属性,否则会报错,因为数据库不认识之前传的字符串。
在程序中会有三种形式传递sql语句:
- 执行拼接的sql语句
- 执行参数化sql语句
- 执行存储过程
其中执行存储过程的性能远高于其他两种性能,第二是参数化,最后一名是拼接sql语句
但是存储过程的安全性不是绝对的,参数化同样相对于拼接的sql语句有更好的安全性。
SqlCommand cmd = new sqlCommand()
cmd.Connection = conn;
cmd.CommandText ="sp_update_student";
cmd.CommandType = CommandType.StoreProcedure;
SqlParameter[] pars =
{
new SqlParameter("@name","zs")//输入参数
new SqlParameter("@result",null)//输出参数
};
pars[1].Direction = ParameterDirection.Output;
调用带参存储过程,获取输出参数值
- 获取输出参数的值时,应确保链接对象已关闭。
int count = convert.ToInt32(pars[1].Value);
例子如下
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace CH03
{
class Program
{
static void Main(string[] args)
{
string conStr = "server=.;database=MySchool;uid=sa;pwd=123456";
//创建数据库链接
SqlConnection con = new SqlConnection(conStr);
//创建SqlConnection对象用以传递数据库链接字符串。
con.Open();
//打开数据库链接
string sql = "proc_stuResultParam";
//创建传入的字符串,并传入存储过程名。
//有参数构建参数化无参数则不用
SqlParameter[] par ={
new SqlParameter("@score",90),
new SqlParameter("@subject","java oop"),//输入参数
new SqlParameter("@count",0),//输出参数,null由存储过程提供
new SqlParameter()//给返回值留空return
};
//用参数化数组的方式传入数据
par[2].Direction = ParameterDirection.Output;//用ParameterDirection方法来设置为输出参数
par[3].Direction = ParameterDirection.ReturnValue;//用parameterDirection方法来设置为返回值
SqlCommand cmd = new SqlCommand(sql,con);//创建sqlCommand对象
cmd.CommandType = CommandType.StoredProcedure;//声明以存储过程的方式执行。
cmd.Parameters.AddRange(par);//将cmd中的参数和将要执行的存储过程中的参数相对应
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))//指明了CommandReader然后调用CommandBehavior.CloseConnetion方法来关闭链接
{
while (reader.Read())
{
Console.WriteLine(reader[0]+" "+reader[1]);
}
}//在数据库链接断掉之后才可以获取到值。
int count = Convert.ToInt32(par[2].Value);//获取存储过程输出参数的值
int r = Convert.ToInt32(par[3].Value);//获取存储过程return返回值的值
Console.WriteLine("输出参数:{0}",count);
Console.WriteLine("返回值:{0}",r);
Console.ReadLine();
}
}
}
用到的存储过程就是之前学存储过程的存储过程proc_stuResultParam
如果是这样的调用数据
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace CH03
{
class Program
{
static void Main(string[] args)
{
string conStr = "server=.;database=MySchool;uid=sa;pwd=123456";
//创建数据库链接
SqlConnection con = new SqlConnection(conStr);
//创建SqlConnection对象用以传递数据库链接字符串。
con.Open();
//打开数据库链接
string sql = "proc_stuResultParam";
//创建传入的字符串,并传入存储过程名。
//有参数构建参数化无参数则不用
SqlParameter[] par ={
new SqlParameter("@score",90),
new SqlParameter("@subject","java oop"),//输入参数
new SqlParameter("@count",0),//输出参数,null由存储过程提供
new SqlParameter()//给返回值留空return
};
//用参数化数组的方式传入数据
par[2].Direction = ParameterDirection.Output;//用ParameterDirection方法来设置为输出参数
par[3].Direction = ParameterDirection.ReturnValue;//用parameterDirection方法来设置为返回值
SqlCommand cmd = new SqlCommand(sql, con);//创建sqlCommand对象
cmd.CommandType = CommandType.StoredProcedure;//声明以存储过程的方式执行。
cmd.Parameters.AddRange(par);//将cmd中的参数和将要执行的存储过程中的参数相对应
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))//指明了CommandReader然后调用CommandBehavior.CloseConnetion方法来关闭链接
{
while (reader.Read())
{
Console.WriteLine(reader[0] + " " + reader[1]);
int count = Convert.ToInt32(par[2].Value);//获取存储过程输出参数的值
int r = Convert.ToInt32(par[3].Value);//获取存储过程return返回值的值
Console.WriteLine("输出参数:{0}", count);
Console.WriteLine("返回值:{0}", r);
}
}//在数据库链接断掉之后才可以获取到值。
Console.ReadLine();
}
}
}
这样的情况虽然可以取到上面三个值,但是下面的返回值和输出参数是取不到的,就如同上面所说:获取输出参数的值时,应确保链接对象已关闭。