博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

在ADO.NET中使用参数化SQL语句的大同小异[转]

Posted on 2008-12-16 11:25  夜路涛涛  阅读(814)  评论(0编辑  收藏  举报
在ADO.NET中经常需要跟各种数据库打交道,在不实用存储过程的情况下,使用参数化SQL语句一定程度上可以防止SQL注入,同时对一些较难赋值的字段(如在SQL Server中Image字段,在Oracle中Clob字段等)使用参数化SQL语句很容易就能赋值,所以本人经常在ADO.NET中使用参数化SQL语句,近几年来陆续跟SQL Server/Oracle/ MySQL/Access打交道,积累了一些心得,现在整理出来供大家参考。ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
我们假设数据可的结构如下图(设置的数据库为Oracle10g):ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
它在SQL Server中的创建语句是:ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
createÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
table S_Admin (ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  UserName           
varchar(60)          not null,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  Password           
varchar(60)          not null,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  Remark             
varchar(50)          null,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  Mail               
varchar(120)        not null,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  AddDate             
datetime null defaultÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
GETDATE(),ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  LoginDate           
datetime null defaultÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
GETDATE(),ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  LoginIP             
varchar(50)          null,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  Active             
smallint null default 1,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  LoginCount         
int null default 1,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
 
PowerÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
int null default 0,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
  Departid           
int null default 0,ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
 
constraint PK_S_ADMIN primary key nonclustered (UserId)ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
)ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
goÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
下面假设数据库的主键都采用了数据库的本地化技术解决了(例如在Access、SQL Server和MySQL中采用自增字段,在Oracle中使用了sequence结合触发器),假如在Oracle中向表中插入一记录的代码如下:ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Data;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Configuration;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.Security;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.WebControls;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.WebControls.WebParts;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.HtmlControls;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Data.OracleClient;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// <summary>ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// 在Oracle中使用参数化SQL的例子ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// </summary>ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
public class OracleUtilÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
{ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
   
public OracleUtil()ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    {ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    }ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
   
public bool InsertAdmin(string userName, string password, string remark, string mail, int departId, int power)ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    {ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
string sql = "insert into S_Admin(UserName,Password,Remark,Mail,DepartId,Power)values(:UserName,:Password,:Remark,:Mail,:DepartId,:Power)";ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        OracleConnection connection
= new OracleConnection();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.ConnectionString
= "";//此处设置链接字符串ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        OracleCommand command = new OracleCommand(sql, connection);ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
":UserName", OracleType.NVarChar, 60).Value = userName;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
":Password", OracleType.NVarChar, 60).Value =password;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
":Remark", OracleType.NVarChar, 60).Value = remark;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
":Mail", OracleType.NVarChar, 60).Value =mail;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
":DepartId", OracleType.Int32, 4).Value =departId;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
":Power", OracleType.Int32, 4).Value = power;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.Open();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
int rowsAffected=command.ExecuteNonQuery();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.Close();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Dispose();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
return rowsAffected > 0;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    }ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
}
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
在MySQL中增加同样一条记录的代码如下(需要到MySQL官方网站下载.net驱动程序):ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Data;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Configuration;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.Security;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.WebControls;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.WebControls.WebParts;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.HtmlControls;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using MySql.Data;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using MySql.Data.MySqlClient;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// <summary>ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// 在MySQL中使用参数化SQL的例子ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// </summary>ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
public class MySqlUtilÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
{ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
   
public MySqlUtil()ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    {ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    }ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
   
public bool InsertAdmin(string userName, string password, string remark, string mail, int departId, int power)ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    {ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
string sql = "insert into S_Admin(UserName,Password,Remark,Mail,DepartId,Power)values(@UserName,@Password,@Remark,@Mail,@DepartId,@Power)";ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        MySqlConnection connection
= new MySqlConnection();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.ConnectionString
= "";//此处设置链接字符串ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        MySqlCommand command = new MySqlCommand(sql, connection);ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@UserName", MySqlDbType.VarChar, 60).Value = userName;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@Password", MySqlDbType.VarChar, 60).Value = password;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@Remark", MySqlDbType.VarChar, 60).Value = remark;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@Mail", MySqlDbType.VarChar, 60).Value = mail;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@DepartId", MySqlDbType.Int32, 4).Value = departId;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@Power", MySqlDbType.Int32, 4).Value = power;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.Open();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
int rowsAffected = command.ExecuteNonQuery();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.Close();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Dispose();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
return rowsAffected > 0;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    }ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
}
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
在SQL Server中增加同样一条记录的代码如下:ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Data;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Data.SqlClient;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Configuration;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.Security;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.WebControls;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.WebControls.WebParts;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.HtmlControls;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// <summary>ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// 在SQL Server中使用参数化SQL的例子ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// </summary>ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
public class SqlUtilÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
{ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
   
public SqlUtil()ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    {ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    }ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
   
public bool InsertAdmin(string userName, string password, string remark, string mail, int departId, int power)ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    {ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
string sql = "insert into S_Admin(UserName,Password,Remark,Mail,DepartId,Power)values(@UserName,@Password,@Remark,@Mail,@DepartId,@Power)";ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        SqlConnection connection
= new SqlConnection();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.ConnectionString
= "";//此处设置链接字符串ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        SqlCommand command = new SqlCommand(sql, connection);ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@UserName",SqlDbType.NVarChar, 60).Value = userName;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@Password", SqlDbType.NVarChar, 60).Value = password;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@Remark", SqlDbType.NVarChar, 60).Value = remark;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@Mail", SqlDbType.NVarChar, 60).Value = mail;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@DepartId", SqlDbType.Int, 4).Value = departId;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"@Power", SqlDbType.Int, 4).Value = power;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.Open();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
int rowsAffected = command.ExecuteNonQuery();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.Close();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Dispose();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
return rowsAffected > 0;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    }ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
}
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
在Access中增加同样一条记录的代码如下:ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Data;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Configuration;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.Security;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.WebControls;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.WebControls.WebParts;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Web.UI.HtmlControls;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
using System.Data.OleDb;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// <summary>ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// 在Access中使用参数化SQL的例子ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
/// </summary>ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
public class AccessUtilÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
{ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
   
public AccessUtil()ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    {ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    }ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
   
public bool InsertAdmin(string userName, string password, string remark, string mail, int departId, int power)ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    {ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
string sql = "insert into S_Admin(UserName,Password,Remark,Mail,DepartId,Power)values(?,?,?,?,?,?)";ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        OleDbConnection connection
= new OleDbConnection();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.ConnectionString
= "";//此处设置链接字符串ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
//注意下面参数的顺序一定要按照sql语句中的插入的列的顺序赋值,否则一定会报异常ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        OleDbCommand command = new OleDbCommand(sql, connection);ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"?", OleDbType.LongVarWChar, 60).Value = userName;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"?", OleDbType.LongVarWChar, 60).Value = password;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"?", OleDbType.LongVarWChar, 60).Value = remark;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"?", OleDbType.LongVarWChar, 60).Value = mail;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"?", OleDbType.Integer, 4).Value = departId;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Parameters.Add(
"?", OleDbType.Integer, 4).Value = power;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.Open();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
int rowsAffected = command.ExecuteNonQuery();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        connection.Close();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
        command.Dispose();ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
       
return rowsAffected > 0;ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
    }ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
}
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
需要说明的是,除了Access之外,操作其它数据库可以不必要按照参数在SQL语句中出现的顺序添加进去一样可以正确执行,但是在Access中一定按照插入的列的顺序添加参数,因为“OLE DB.NET Framework 数据提供程序使用标有问号 (?) 的定位参数,而不使用命名参数(MSDN)”,所以给添加参数和赋值一定要按照列的顺序。ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\
通过上面的例子,基本上可以总结出一个规律:在参数化SQL中参数名的格式跟其在存储过程中生命存储过程参数一致,例如在Oracle中存储过程参数一律以”:”开头,在MS SQL Server中存储过程参数一律以”@”开头,而在MySQL中存储过程(MySQL5.0以后版本支持存储过程)参数一律以“?”开头,所以在参数化SQL语句中参数名有些不一样(记得在csdn上有朋友提到过不知道为什么MySQL中参数化SQL语句中要用“?而不是和SQL Server一样使用”@”),如果那位朋友看过本文,我想他就会解开这个疑虑了。ÆïǾLâ½íwww.netcsharp.cnQfòç=€û\