SqlParameter用法
关于Sql注入的基本概念,相信不需多说,大家都清楚,经典的注入语句是'or1=1--
单引号而截断字符串,“or1=1”的永真式的出现使得表的一些信息被暴露出来,如果sql语句是select*from的话,可能你整个表的信息都会被读取到,更严重的是,如果恶意使用都使用drop命令,那么可能你的整个数据库得全线崩溃。
当然,现在重点不是讲sql注入的害处,而是说说如何最大限度的避免注入问题。
sql注入的存在在最大危害,是sql的执行语句没有和控制语句分开,我们想要select一些东西,但用户可能拼出'or1=1甚至再加上delete/update/drop,后来是属于控制语句了,所以要避免sql的注入,就必须把查询语句与控制语句分开。
SqlParameter给我们提供了一个很好的类,有了它,我们可以不现拼接字符串,也可以不再担心单引号带来的惨剧,因为,这一切会有人来为我们完成的。
简单的给个示例
传统的查询语句的sql可能为
stringsql="select*fromuserswhereuser_id='"+Request.QueryString["uid"]+"'";
很显然,我们在这里拼接了字符串,这就给sql注入留下了可乘之机。
现在,我们要改写这样的语句,使用SqlParameter来做
SqlCommandSqlCmd=newSqlCommand(sql,SqlConn);
SqlParameter_userid=newSqlParameter("uid",SqlDbType.Int);
_userid.Value=Request.QueryString["u_id"];
SqlCmd.Parameters.Add(_userid);
这样,我们可以保证外接参数能被正确的转换,单引号这些危险的字符也会转义了,不会再对库造成威胁。
当然,这仅是一个示例而已,在真实的情况下,可能你还要对Request.QueryString["u_id"]进行必要的检测与分析,这样才安全
所以,使用参数化的sql语句,是一种很好的做法
DimsqlAsStringBuilder=NewStringBuilder()
sql.Append("")
sql.Append("SELECT*FROMtest")
sql.Append("WHEREa=@p1")
DimcommandAsSqlCommand=dac.CreateCommand(sql.ToString())'dac为自己写的类
DimparamAsSqlParameter=NewSqlParameter()
param.ParameterName="@p1"
param.SqlDbType=SqlDbType.NVarChar
param.Value=b'b为该函数的参数(ByValbasString)
command.Parameters.Add(param)
DimreaderAsSqlDataReader=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#
publicSqlParameter(
stringparameterName,
SqlDbTypedbType,
intsize,
ParameterDirectiondirection,
byteprecision,
bytescale,
stringsourceColumn,
DataRowVersionsourceVersion,
boolsourceColumnNullMapping,
Objectvalue,
stringxmlSchemaCollectionDatabase,
stringxmlSchemaCollectionOwningSchema,
stringxmlSchemaCollectionName
)
参数
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
[VisualBasic]
NotInheritablePublicClassSqlParameter
InheritsMarshalByRefObject
ImplementsIDbDataParameter,IDataParameter,ICloneable
[C#]
publicsealedclassSqlParameter:MarshalByRefObject,
IDbDataParameter,IDataParameter,ICloneable
[C++]
public__gc__sealedclassSqlParameter:public
MarshalByRefObject,IDbDataParameter,IDataParameter,ICloneable
[JScript]
publicclassSqlParameterextendsMarshalByRefObjectimplements
IDbDataParameter,IDataParameter,ICloneable
线程安全
此类型的所有公共静态(VisualBasic中为Shared)成员是线程安全的。但不保证任何实例成员是线程安全的。
备注
参数名称不区分大小写。
示例
[VisualBasic,C#,C++]下面的示例通过SqlDataAdapter中的SqlParameterCollection集合创建SqlParameter的多个实例。这些参数用于从数据源中选择数据并将数据放在DataSet中。此示例假定已经用适当的架构、命令和连接创建了DataSet和SqlDataAdapter。
[VisualBasic]
PublicSubAddSqlParameters()
'...
'createmyDataSetandmyDataAdapter
'...
myDataAdapter.SelectCommand.Parameters.Add("@CategoryName",SqlDbType.VarChar,80).Value="toasters"
myDataAdapter.SelectCommand.Parameters.Add("@SerialNum",SqlDbType.Int).Value=239
myDataAdapter.Fill(myDataSet)
EndSub'AddSqlParameters
[C#]
publicvoidAddSqlParameters()
{
//...
//createmyDataSetandmyDataAdapter
//...
myDataAdapter.SelectCommand.Parameters.Add("@CategoryName",SqlDbType.VarChar,80).Value="toasters";
myDataAdapter.SelectCommand.Parameters.Add("@SerialNum",SqlDbType.Int).Value=239;
myDataAdapter.Fill(myDataSet);
}
[C++]
public:
voidAddSqlParameters()
{
//...
//createmyDataSetandmyDataAdapter
//...
myDataAdapter->SelectCommand->Parameters->Add(S"@CategoryName",SqlDbType::VarChar,80)->Value=S"toasters";
myDataAdapter->SelectCommand->Parameters->Add(S"@SerialNum",SqlDbType::Int)->Value=__box(239);
myDataAdapter->Fill(myDataSet);
}
[JScript]没有可用于JScript的示例。若要查看VisualBasic、C#或C++示例,请单击页左上角的“语言筛选器”按钮。
要求
命名空间:System.Data.SqlClient
平台:Windows98,WindowsNT4.0,WindowsME,Windows2000,WindowsXPHomeEdition,WindowsXPProfessional,WindowsServer2003系列,.NETFramework精简版
程序集: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
例如
SqlParameterparm=newSqlParameter(PARM_ORDER_ID,SqlDbType.Int);
parm.Value=orderId;
之后能不能再改parm添加一个值
因为我写了个方法是传递SqlParameter类型的参数
但有时要做些判断
像
SqlParameterparm=newSqlParameter(PARM_ORDER_ID,SqlDbType.Int);
parm.Value=orderId;
if(...)
{
//添加一个参数
}
ExecuteReader(parm,.....);
请问应该怎么做呢
最佳答案intIArticle.Insert(ArticleInfoarticle)
{
//如果对象存在
if(article.ID!=-1)
return-1;
else
article.ID=TableHelper.GetSequence(SQLHelper.ConnectionString,"Article","ID");
//统计执行成功的数量
intsuccessCount=0;
stringSQL_THIS=SQL_INSERT_ARTICLE;
SqlParameter[]paras=GetParas();
paras[0].Value=article.ID;
paras[1].Value=article.Title;
paras[2].Value=article.DateAdded;
paras[3].Value=article.Text;
paras[4].Value=article.SourceUrl;
paras[5].Value=article.PostType;
paras[6].Value=article.Author;
paras[7].Value=article.Email;
paras[8].Value=article.SourceName;
paras[9].Value=article.BlogID;
paras[10].Value=article.CategoryID;
paras[11].Value=article.Summary;
paras[12].Value=article.IsBySummary;
paras[13].Value=article.DateUpdated;
paras[14].Value=article.TitleUrl;
paras[15].Value=article.FeedBackCount;
paras[16].Value=article.PostConfig;
paras[17].Value=article.EntryName;
paras[18].Value=article.KeyWord;
SqlConnectionconn=newSqlConnection(SQLHelper.ConnectionString);
successCount=SQLHelper.ExecuteNonQuery(conn,CommandType.Text,SQL_THIS,paras);
returnsuccessCount;
}