为了防止Sql注入我们使用参数化查询的方法,为了节省Sql语句的编译时间我们使用存储过程,这两个看似毫不相干的东西,其实是同一个玩意,不信看我给你解释。
普通Sql语句可以增删改查,参数化查询和存储过程也可以增删改查,这里就不对四种操作逐个写例子了,写insert和select的例子来说明情况即可。
参数化查询:
执行参数化查询代码:
public static int ParamInsert(string userId, string userName, string gender)
{
int rowNumber = -100;
string connString = ConfigurationManager.ConnectionStrings["connString"].ToString();
SqlConnection con = new SqlConnection(connString);
con.Open();
#region 参数化插入
SqlCommand cmd1 = new SqlCommand("insert into UserInfo values(@userId,@userName,getdate(),@gender)", con);
cmd1.Parameters.Add("@userId", SqlDbType.Int).Value = userId;
cmd1.Parameters.Add("@userName", SqlDbType.NVarChar, 20).Value = userName;
cmd1.Parameters.Add("@gender", SqlDbType.NVarChar, 2).Value = gender;
rowNumber = cmd1.ExecuteNonQuery();
cmd1.Dispose();
#endregion
#region 参数化查询
SqlCommand cmd = new SqlCommand("select * from UserInfo where UserId = @UserId", con);
cmd.Parameters.Add("@UserId", SqlDbType.Int).Value = userId;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds, "userInfo");
DataTable dt = ds.Tables[0];
DataRow row = dt.Rows[0];
cmd.Dispose();
#endregion
con.Close();
return rowNumber;
}
参数化查询与普通查询的区别在sql语句地书写上,
普通语句查询:
“select * from UserInfo where UserId = ” + userId
参数化查询:
“select * from UserInfo where UserId = @UserId”;
cmd.Parameters.Add();
普通语句插入:
string.Format(“insert into UserInfo values({0},{1},{2},{3})”,userId,userName,”getdate()”,gender);
参数化插入:
“insert into UserInfo values(@userId,@userName,getdate(),@gender)”;
cmd.Parameters.Add()
参数化查询是用@+字段名做标记表示此处要输入东西,然后通过cmd.Parameters.Add()对这些标记赋予具体类型并进行赋值。
存储过程:
创建insert存储过程代码
CREATE PROCEDURE [dbo].[Proc_InsertUserInfo]
@UserId int,
@UserName nvarchar(20),
@AddTime datetime,
@Gender nvarchar(2)
AS
BEGIN
SET NOCOUNT ON;
insert into dbo.UserInfo values(@UserId,@UserName,@AddTime,@Gender)
END
创建select存储过程代码
ALTER PROCEDURE [dbo].[Proc_SelectUserInfo]
@UserId int
AS
BEGIN
SET NOCOUNT ON;
SELECT * from dbo.UserInfo where UserId=@UserId
END
执行存储过程代码:
public static int Insert(string userId,string userName,string gender)
{
int rowNumber = -100;
string strConnection = ConfigurationManager.ConnectionStrings["connString"].ToString();
SqlConnection con = new SqlConnection(strConnection);
con.Open();
#region 存储过程插入
SqlCommand cmd1 = new SqlCommand("Proc_InsertUserInfo", con);
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Parameters.Add("@UserId", SqlDbType.Int).Value = userId; ;
cmd1.Parameters.Add("@UserName", SqlDbType.NVarChar, 20).Value = userName;
cmd1.Parameters.Add("@AddTime", SqlDbType.DateTime).Value = DateTime.Now.ToString();
cmd1.Parameters.Add("@Gender", SqlDbType.NVarChar, 2).Value = gender == "1" ? "男" : "女";
rowNumber = cmd1.ExecuteNonQuery();
cmd1.Dispose();
#endregion
#region 存储过程查询
SqlCommand cmd = new SqlCommand("Proc_SelectUserInfo", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@UserId", SqlDbType.Int).Value = userId;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
rowNumber = adapter.Fill(ds, "userInfo");
DataTable dt = ds.Tables[0];
DataRow row = dt.Rows[0];
#endregion
con.Close(a);
return rowNumber;
}
存储过程中的插入代码:
insert into dbo.UserInfo values(@UserId,@UserName,@AddTime,@Gender)
存储过程中的查询代码:
select * from dbo.UserInfo where UserId=@UserId
调用存储过程方式:
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add();
如果执行结果返回数据表,那也照样可以用SqlDataAdapter和DataSet来获取到,跟普通的Sql语句没什么两样,只不过存储过程需要先声明变量才能在Sql语句中使用,再者节省了Sql语句的编译时间,提高了效率。
结论
参数化查询和存储过程在声明方式和使用方式上大体相同,不同点有3:
- 参数化查询直接用@+参数名作为参数化的标记,存储过程也是这样的,不过存储过程中要先声明一下这个标记的类型,才能使用
- 参数化查询SqlCommand cmd = new SqlCommand(“Sql语句”, con);
存储过程查询SqlCommand cmd = new SqlCommand(“存储过程名称”, con); - 调用存储过程要指明此处使用的是存储过程,cmd.CommandType =CommandType.StoredProcedure;,
默认使用的是CommandType.Text