首页 > 代码库 > SqlParameter的用法和好处

SqlParameter的用法和好处

关于Sql注入的基本概念,相信不需要多说,大家都清楚,经典的注入语句是‘ or 1=1--
单引号而截断字符串,“or 1=1”的永真式的出现使得表的一些信息被暴露出来,如果sql语句是select * from 的话,可能你整个表的信息都会被读取到,更严重的是,如果恶意使用都使用drop命令,那么可能你的整个数据库得全线崩溃。
当然,现在重点不是讲sql注入的害处,而是说说如何最大限度的避免注入问题。
sql注入的存在在最大危害,是sql的执行语句没有和控制语句分开,我们想要select一些东西,但用户可能拼出‘ or 1=1甚至再加上delete/update/drop,后来是属于控制语句了,所以要避免sql的注入,就必须把查询语句与控制语句分开。
SqlParameter给我们提供了一个很好的类,有了它,我们可以不现拼接字符串,也可以不再担心单引号带来的惨剧,因为,这一切会有人来为我们完成的。
简单的给个示例
传统的查询语句的sql可能为
string sql="select * from users where user_id=‘"+Request.QueryString["uid"]+"‘";
很显然,我们在这里拼接了字符串,这就给sql注入留下了可乘之机。
现在,我们要改写这样的语句,使用SqlParameter来做
SqlCommand SqlCmd = new SqlCommand(sql, SqlConn);
SqlParameter _userid = new SqlParameter("uid", SqlDbType.Int);
_userid.Value = http://www.mamicode.com/Request.QueryString["u_id"];
SqlCmd.Parameters.Add(_userid);
这样,我们可以保证外接参数能被正确的转换,单引号这些危险的字符也会转义了,不会再对库造成威胁。
当然,这仅是一个示例而已,在真实的情况下,可能你还要对 Request.QueryString["u_id"]进行必要的检测与分析,这样才安全
所以,使用参数化的sql语句,是一种很好的做法

Dim sql As StringBuilder = New StringBuilder()sql.Append("")sql.Append("SELECT * FROM test")sql.Append(" WHERE  a= @p1 ")           Dim command As SqlCommand    =    dac.CreateCommand(sql.ToString())  dac为自己写的类Dim param As SqlParameter = New SqlParameter()param .ParameterName = "@p1"param .SqlDbType = SqlDbType.NVarCharparam .Value = b       b为该函数的参数(ByVal b as String)command .Parameters.Add(param)Dim reader As SqlDataReader = command.ExecuteReader()

SqlParameter 构造函数
SqlParameter 构造函数 (String, SqlDbType, Int32, ParameterDirection, Byte, Byte, String, DataRowVersion, Boolean, Object, String, String, String)
初始化 SqlParameter 类的一个新实例,该类使用参数名、参数的类型、参数的长度、方向、精度、小数位数、源列名称、DataRowVersion 值之一、用于源列映射的布尔值、SqlParameter 的值、此 XML 实例的架构集合所在的数据库的名称、此 XML 实例的架构集合所在的关系架构以及此参数的架构集合的名称。
命名空间: System.Data.SqlClient
程序集: System.Data(在 system.data.dll 中)

C#:

public SqlParameter (    string parameterName,    SqlDbType dbType,    int size,    ParameterDirection direction,    byte precision,    byte scale,    string sourceColumn,    DataRowVersion sourceVersion,    bool sourceColumnNullMapping,    Object value,    string xmlSchemaCollectionDatabase,    string xmlSchemaCollectionOwningSchema,    string xmlSchemaCollectionName)

参数
parameterName
要映射的参数的名称。
dbType
SqlDbType 值之一。
size
参数的长度。
direction
ParameterDirection 值之一。
precision
要将 Value 解析为的小数点左右两侧的总位数。
scale
要将 Value 解析为的总小数位数。
sourceColumn
源列的名称。
sourceVersion
DataRowVersion 值之一。
sourceColumnNullMapping
如果源列可为空,则为 true;如果不可为空,则为 false。
value
一个 Object,它是 SqlParameter 的值。
xmlSchemaCollectionDatabase
此 XML 实例的架构集合所在的数据库的名称。
xmlSchemaCollectionOwningSchema
包含此 XML 实例的架构集合的关系架构。
xmlSchemaCollectionName
此参数的架构集合的名称。
备注
如果未在 size 和 precision 参数中显式设置 Size 和 Precision,则从 dbType 参数的值推断出它们。
SqlParameter 类
表示 SqlCommand 的参数,也可以是它到 DataSet 列的映射。无法继承此类。
有关此类型所有成员的列表,请参阅 SqlParameter 成员。
System.Object
System.MarshalByRefObject
System.Data.SqlClient.SqlParameter
[Visual Basic]

NotInheritable Public Class SqlParameterInherits MarshalByRefObjectImplements IDbDataParameter, IDataParameter, ICloneable

[C#]
public sealed class SqlParameter : MarshalByRefObject,IDbDataParameter, IDataParameter, ICloneable

[C++]
public __gc __sealed class SqlParameter : publicMarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable[JScript]public class SqlParameter extends MarshalByRefObject implementsIDbDataParameter, IDataParameter, ICloneable

线程安全
此类型的所有公共静态(Visual Basic 中为 Shared)成员是线程安全的。但不保证任何实例成员是线程安全的。
备注
参数名称不区分大小写。
示例
[Visual Basic, C#, C++] 下面的示例通过 SqlDataAdapter 中的 SqlParameterCollection 集合创建 SqlParameter 的多个实例。这些参数用于从数据源中选择数据并将数据放在 DataSet 中。此示例假定已经用适当的架构、命令和连接创建了 DataSet 和 SqlDataAdapter。
[Visual Basic]

Public Sub AddSqlParameters() ... create myDataSet and myDataAdapter ...myDataAdapter.SelectCommand.Parameters.Add("@CategoryName", SqlDbType.VarChar, 80).Value = http://www.mamicode.com/"toasters"myDataAdapter.SelectCommand.Parameters.Add("@SerialNum", SqlDbType.Int).Value = http://www.mamicode.com/239myDataAdapter.Fill(myDataSet)End Sub AddSqlParameters

[C#]

public void AddSqlParameters(){// ...// create myDataSet and myDataAdapter// ...myDataAdapter.SelectCommand.Parameters.Add("@CategoryName", SqlDbType.VarChar, 80).Value = http://www.mamicode.com/"toasters";myDataAdapter.SelectCommand.Parameters.Add("@SerialNum", SqlDbType.Int).Value = http://www.mamicode.com/239;myDataAdapter.Fill(myDataSet);}


[C++]

public:void AddSqlParameters(){// ...// create myDataSet and myDataAdapter// ...myDataAdapter->SelectCommand->Parameters->Add(S"@CategoryName", SqlDbType::VarChar, 80)->Value = http://www.mamicode.com/S"toasters";myDataAdapter->SelectCommand->Parameters->Add(S"@SerialNum", SqlDbType::Int)->Value = http://www.mamicode.com/__box(239);myDataAdapter->Fill(myDataSet);}


[JScript] 没有可用于 JScript 的示例。若要查看 Visual Basic、C# 或 C++ 示例,请单击页左上角的“语言筛选器”按钮 。
要求
命名空间: System.Data.SqlClient
平台: Windows 98, Windows NT 4.0, Windows ME, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 系列, .NET Framework 精简版
程序集: System.Data (在 System.Data.dll 中)
使用SqlParameter

SqlParameter[] p ={SqlHelper.MakeInParam("@EntryID",SqlDbType.Int,4,ev.EntryID),SqlHelper.MakeInParam("@BlogID",SqlDbType.Int,4,ev.BlogID),SqlHelper.MakeInParam("@URL",SqlDbType.NVarChar,255,DataHelper.CheckNull(ev.ReferralUrl)),SqlHelper.MakeInParam("@IsWeb",SqlDbType.Bit,1,ev.PageViewType)};SqlHelper.ExecuteNonQuery(conn,CommandType.StoredProcedure,"blog_TrackEntry",p);

答疑:SqlParameter赋值之后怎么添加值
用SqlCommand我知道用add
但我想问的是  SqlParameter
例如

SqlParameter  parm  =  new  SqlParameter(PARM_ORDER_ID,  SqlDbType.Int);parm.Value  =  orderId;


之后能不能再改parm添加一个值
因为我写了个方法是传递SqlParameter类型的参数
但有时要做些判断

SqlParameter  parm  =  new  SqlParameter(PARM_ORDER_ID,  SqlDbType.Int);parm.Value  =  orderId;if(...){//添加一个参数}ExecuteReader(parm,.....);


请问应该怎么做呢
最佳答案 

int IArticle.Insert(ArticleInfo article){//如果对象存在if (article.ID != -1)return -1;elsearticle.ID = TableHelper.GetSequence(SQLHelper.ConnectionString, "Article", "ID");//统计执行成功的数量int successCount = 0;string SQL_THIS = SQL_INSERT_ARTICLE;SqlParameter[] paras = GetParas();paras[0].Value =http://www.mamicode.com/ article.ID;paras[1].Value =http://www.mamicode.com/ article.Title;paras[2].Value =http://www.mamicode.com/ article.DateAdded;paras[3].Value =http://www.mamicode.com/ article.Text;paras[4].Value =http://www.mamicode.com/ article.SourceUrl;paras[5].Value =http://www.mamicode.com/ article.PostType;paras[6].Value =http://www.mamicode.com/ article.Author;paras[7].Value =http://www.mamicode.com/ article.Email;paras[8].Value =http://www.mamicode.com/ article.SourceName;paras[9].Value =http://www.mamicode.com/ article.BlogID;paras[10].Value =http://www.mamicode.com/ article.CategoryID;paras[11].Value =http://www.mamicode.com/ article.Summary;paras[12].Value =http://www.mamicode.com/ article.IsBySummary;paras[13].Value =http://www.mamicode.com/ article.DateUpdated;paras[14].Value =http://www.mamicode.com/ article.TitleUrl;paras[15].Value =http://www.mamicode.com/ article.FeedBackCount;paras[16].Value =http://www.mamicode.com/ article.PostConfig;paras[17].Value =http://www.mamicode.com/ article.EntryName;paras[18].Value =http://www.mamicode.com/ article.KeyWord;SqlConnection conn = new SqlConnection(SQLHelper.ConnectionString);successCount = SQLHelper.ExecuteNonQuery(conn, CommandType.Text, SQL_THIS, paras);return successCount;}

原文出自:http://www.cnblogs.com/angelfeather/articles/1225902.html