在更新DataTable或是DataSet时,如果不采用SqlParameter,当输入的Sql语句出现歧义,如字符串中含有单引号,程序就会发生错误,并且可以轻易地通过拼接Sql语句来进行注入攻击。
SqlCommand对象可使用参数(SqlParameter)来将值传递给 SQL 语句或存储过程。与命令文本不同,参数输入被视为文本值,而不是可执行代码。
其次,SqlParameter还可提高查询执行性能,因为它们可帮助数据库服务器将传入命令与适当的缓存查询计划进行准确匹配。
不同数据源对应的Parameter对象
Paramter对象的属性
•DbType: 获取或设置参数的数据类型。
•Direction: 获取或设置一个值,该值指示参数是否只可输入、只可输出、双向还是存储过程返回值参数。
•IsNullable: 获取或设置一个值,该值指示参数是否可以为空。
•ParamteterName: 获取或设置DbParamter的名称。
•Size: 获取或设置列中数据的最大大小。
•Value: 获取或设置该参数的值。
案例代码:修改客户资料
1,项目组织文件的架构说明
1、代码文件MshConnection.cs,实现连接数据库,构造SqlConnection对象
2、代码文件MshCommand.cs, 实现数据库CURD操作,构造SqlCommand对象
3、代码文件MshBusinessLogic.cs,实现客户需求的业务逻辑类,比如拼接SQL语句与参数,返回调用结果
4、代码文件Program.cs,主要是包含mian()函数,调用业务逻辑
2,四个文件的相关代码,如下
MshConnection.cs文件,代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace SqlCommandParameter
{
class MshConnection
{
private SqlConnection conn = null; //类变量:存放SqlConnection对象
private bool flage = false; //对象创建是否成功标志:false/true
private string runCLassInfo = null; //对象运行期间信息
public MshConnection()
{
//1.构造连接字符串的方法
SqlConnectionStringBuilder connStr = new SqlConnectionStringBuilder();
connStr.DataSource = "192.168.1.20";
connStr.InitialCatalog = "mshDB_Debug";
connStr.UserID = "developer";
connStr.Password = "developer";
connStr.Pooling = true;
connStr.MaxPoolSize = 1000;
connStr.MinPoolSize = 1;
//2.创建Connection对象
try
{
this.conn = new SqlConnection(connStr.ToString());
if (conn != null)
{
this.flage = true; //创建对象成功为true
this.runCLassInfo += "\n1.Create SqlConnection Object Success!";
}
}
catch (Exception ex)
{
this.runCLassInfo += "\n1.Create SqlConnection Object Failure:" + ex.Message;
this.flage = false;
}
} //构造Connection对象
public bool Flage
{
get
{
return this.flage;
}
}
public string RunClassInfo
{
get
{
return this.runCLassInfo;
}
}
public SqlConnection Connection
{
get
{
return this.conn;
}
}
}
}
MshCommand.cs
文件,代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace SqlCommandParameter
{
class MshCommand
{
private SqlConnection conn = null;
private SqlCommand sqlcmd = null;
private StringBuilder strSQLText = null; //SQL语句
private SqlParameter[] paras = null; //传入参数
private string runClassInfo = null; //保存类运行期间信息
private string Error = null;
public MshCommand()
{
MshConnection mshconn = new MshConnection(); //1.生成connection对象
this.conn = mshconn.Connection;
this.runClassInfo += "\n1.Create SqlConnection Object Success!";
this.sqlcmd = new SqlCommand();
this.sqlcmd.Connection = this.conn; //2.给Command对象接上Connection对象
this.runClassInfo += "\n2.Create SqlCommand Object Success!";
}
~MshCommand()
{
this.conn.Dispose();
}
public string RunClassInfo
{
get
{
return this.runClassInfo;
}
}
public StringBuilder StrSQLText //类公共属性:SQL语句
{
get
{
return this.strSQLText;
}
set
{
this.strSQLText = value;
sqlcmd.CommandText = this.strSQLText.ToString(); //赋予查询SQL语句
sqlcmd.CommandType = CommandType.Text;
}
}
public SqlParameter[] Paras //类公共属性:SQL语句的参数(数组)
{
get
{
return this.paras;
}
set
{
this.paras = value;
//遍历添加到Parameters集合中
foreach (var item in this.paras)
{
sqlcmd.Parameters.Add(item);
}
}
}
public int ExecuteScalar() //执行ExecuteScalar()方法,获取单值
{
int result = 0;
try
{
this.conn.Open(); //打开与数据库的连接
result = (int)this.sqlcmd.ExecuteScalar();
return result;
}
catch (Exception ex)
{
this.Error = ex.Message;
return result;
}
finally
{
this.conn.Close(); //显示关闭与数据库的连接
}
}
public int ExecuteNonQuery()
{
int result = 0;
try
{
this.conn.Open();
this.runClassInfo += "\n3.Open SqlConnecte DB Success!";
result = this.sqlcmd.ExecuteNonQuery();
return result;
}
catch (Exception ex)
{
this.Error = ex.Message;
return result;
}
finally
{
this.conn.Close();
this.runClassInfo += "\n4.Closed SqlConnecte DB Success!";
}
}
}
}
MshBusinessLogic.cs文件,代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace SqlCommandParameter
{
class MshBusinessLogic
{
//往客户表中插入一行记录
public void InsertCustomer()
{
int rows = 0;
//拼接SQL语句
StringBuilder strSQL = new StringBuilder();
strSQL.Append("insert into tb_Customer ");
strSQL.Append("values(");
strSQL.Append("@Name,@Sex,@CustomerType,@Phone,@Email,@ContactAddress,@Lat,@Lng,@Postalcode,@Remark");
strSQL.Append(")");
//构造Parameter对象
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter("@Name", SqlDbType.VarChar, 20),
new SqlParameter("@Sex",SqlDbType.Char,1),
new SqlParameter("@CustomerType", SqlDbType.Char, 1),
new SqlParameter("@Phone", SqlDbType.VarChar, 12),
new SqlParameter("@Email", SqlDbType.VarChar, 50),
new SqlParameter("@ContactAddress", SqlDbType.VarChar, 200),
new SqlParameter("@Lat", SqlDbType.Float, 10),
new SqlParameter("@Lng", SqlDbType.Float, 10),
new SqlParameter("@Postalcode", SqlDbType.VarChar, 10),
new SqlParameter("@Remark", SqlDbType.VarChar, 20)
};
//给Parater对象赋值
paras[0].Value = "测试用户";
paras[1].Value = "0";
paras[2].Value = "0";
paras[3].Value = "138222233";
paras[4].Value = "[email protected]";
paras[5].Value = "广东省深圳市宝安区";
paras[6].Value = 12234567890123.456789;
paras[7].Value = 34.222234;
paras[8].Value = "314200";
paras[9].Value = "备注信息";
//生成SqlCommand对象来执行上述SQl语句
MshCommand cmd = new MshCommand();
cmd.StrSQLText = strSQL;
cmd.Paras = paras;
rows += cmd.ExecuteNonQuery();
rows += cmd.ExecuteNonQuery();
Console.WriteLine("Insert Success:{0}rows", rows);
}
//更新客户信息,熟悉SqlParameter对象的使用
public void UpdateCustomer()
{
//拼接SQL语句
StringBuilder strSQL = new StringBuilder();
strSQL.Append("Update tb_Customer Set ");
strSQL.Append("Phone = @Phone,");
strSQL.Append("Email = @Email,");
strSQL.Append("ContactAddress = @Address ");
strSQL.Append("where Name = @Name");
//构造Parameter对象
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter("@Phone", SqlDbType.VarChar, 12),
new SqlParameter("@Email", SqlDbType.VarChar, 50),
new SqlParameter("@Address", SqlDbType.VarChar, 200),
new SqlParameter("@Name", SqlDbType.VarChar, 20)
};
//给Parater对象赋值
paras[0].Value = "18665691100";
paras[1].Value = "[email protected]";
paras[2].Value = "中国深圳市南山区";
paras[3].Value = "Kemi";
//生成SqlCommand对象来执行上述SQl语句
MshCommand cmd = new MshCommand();
cmd.StrSQLText = strSQL;
cmd.Paras = paras;
int rows = cmd.ExecuteNonQuery();
Console.WriteLine("Update Success:{0}rows", rows);
}
//获取插入行的ID,熟悉OUTPUT参数的使用
public void getInsertedID()
{
//拼接SQL语句
StringBuilder strSQL = new StringBuilder();
strSQL.Append("insert tb_Customer(Name) ");
strSQL.Append("OUTPUT inserted.ID values(@Name)");
//构造Parameter对象
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter("@Name", SqlDbType.VarChar, 20)
};
////给Parater对象赋值
paras[0].Value = "Kemi";
//生成SqlCommand对象来执行上述SQl语句
MshCommand cmd = new MshCommand();
cmd.StrSQLText = strSQL;
cmd.Paras = paras;
int insertedID = cmd.ExecuteScalar();
Console.WriteLine("Inserted ID:{0}", insertedID);
}
}
}
运行如下
小结
SqlCommand对象包含一个Paramters集合,当执行命令时,同时将SQL文本,占位符和参数集合传递给数据库。
对于不同的数据源来说,占位符不同:
SQLServer数据源用@parametername格式来命名参数
OleDb以及Odbc数据源均用问号(?)来标识参数位置
Oracle则以:parmname格式使用命名参数。