asp.net 用parameter对象更新数据2011-03-24 22:24asp.net 用parameter对象更新数据

本文介绍了如何在ASP.NET中利用Parameter对象进行SQL Server数据库的更新操作,包括数据插入和异常处理。
摘要由CSDN通过智能技术生成

asp.net 用parameter对象更新数据

部分摘自asp.net3.5从入门到精通c#2008

  asp.net要执行删除和更新操作实际并不复杂,只要使用一个数据命令(Command)对象,使用Update, Insert 或者Delete 这三个语句之一。在执行删除、更新或插入操作时,并不需要获取获取数据,因此也并不需要使用DataReader对象。

  要执行Updata、Insert或者 Delete语句,只需要创建一个数据命令(Command)对象,然后调用其ExecuteNonQuery()方法来执行数据命令。ExecuteNonQuery()方法将返回受影响的记录数,可以通过检查该方法的返回值,以判断对数据库的操作是否执行成功。例如,如果试图执行一个更新或者删除操作,但是ExecuteNonQuery()方法的返回值为0,则表示操作失败,这个能使由于数据库中并不存在于Where子句中的筛选条件相匹配的记录。(另外,如果该SQL命令具有语法错误,或者该SQL命令试图检索一个数据库中并不存在的表时,将会产生异常。)

 

这里只说一下更新的方法,先是不安全的代码:

 

代码
string insertSQL;
insertSQL
= " INSERT INTO Authors ( " ;
insertSQL
+= " au_id, au_fname, au_lname, " ;
insertSQL
+= " phone, adress, sity, state, zip, contract) " ;
insertSQL
+= " VALUES (' " ;
insertSQL
+= txtID.Text + " ', ' " ;
insertSQL
+= txtFirstName.Text + " ', ' " ;
insertSQL
+= ...
...
...
insertSQL
+= txtZip.Text + " ') " ;

SqlConnection con
= new SqlConnection(connectionString);
SqlCommand cmd
= new SqlCommand(insertSQL, con);

// 尝试打开数据库连接并执行更新。
int added = 0 ;
try
{
  con.Open();
  added
= cmd.ExecteNonQuery();
  lblStatus.Text
= added.ToString() + " records inserted. " ;
}
catch (Exception err)
{
  lblStatus.Text
= " Error inserting record. " ;
  lblStatus.Text
+= err.Message;
}
finally
{
  con.Close();
}

// added判断操作是否成功

 

  这个例子是把字符串在代码中连接起来组成一个SQL字符串,然后再通过command执行这个动态生成的SQL语句。这个办法虽然简单但是存在很大的缺陷,如果用户无意或有意的输入一些特殊字符如单引号(')或者注入一些恶意代码,后果就严重了。

  为了创建更加稳定的数据命令,可以使用ado.net的参数化数据命令(parameterized command)。在参数化数据命令中,使用参数作为占位符来替代硬编码的值。下面是更改后的代码(更改的地方用下划线):

 

代码
string insertSQL;
insertSQL
= " INSERT INTO Authors ( " ;
insertSQL
+= " au_id, au_fname, au_lname, " ;
insertSQL
+= " phone, adress, sity, state, zip, contract) " ; "
insertSQL += " VALUES (' " ;
insertSQL
+="@au_id, @au_fname, @au_lname, ";
insertSQL
+="@phone, @address, @city, @state, @zip, @contract)"
;

SqlConnection con
= new SqlConnection(connectionString);
SqlCommand cmd
= new SqlCommand(insertSQL, con);

cmd.Parameters.AddWithValue(
"@au_id", txtID.Text);
cmd.Parameters.AddWithValue(
"@au_fname", txtFirstName.Text);
cmd.Parameters.AddWithValue(
"@au_lname", txtLastName.Text);
cmd.Parameters.AddWithValue(
"@phone", txtPhone.Text);
...
...
...
cmd.Parameters.AddWithValue(
"@zip"
, txtZip.Text);

// 尝试打开数据库连接并执行更新。
int added = 0 ;
try
{
  con.Open();
  added
= cmd.ExecteNonQuery();
  lblStatus.Text
= added.ToString() + " records inserted. " ;
}
catch (Exception err)
{
  lblStatus.Text
= " Error inserting record. " ;
  lblStatus.Text
+= err.Message;
}
finally
{
  con.Close();
}

// added判断操作是否成功

 

 

 

对于不同的数据提供程序,参数化数据命令的语法是不同的。对于SQL Server,参数名可以任意选取,但是必须以@字符开通。通常情况下我们将@使用的字段名作为相应的参数名。而OLE DB是用?来占位。通过addwithvalue来添加parameter对象,当然添加的顺序是无关紧要的。

这样在参数中出现的引号或者SQL语句片段将不会对SQL命令的执行造成任何问题。

 

书上的描述到这里为止,看了一下网上的其实还有另一种添加方法:Parameters.Add(...),它和之前的Parameters.AddWithValue(...)区别是:

" 在.Net Framework 2.0中SqlClient增加了AddWithValue(string parameterName, object value)方法。
该方法简化了调用储存过程的输入参数过程,在运行时对所输入的数据类型进行判断,获取对应的数据库类型。
因此该方法在运行效率上比用Add(string parameterName, SqlDbType sqlDbType, int size, string sourceColumn)方法要低。
在效率要求较高的地方仍然建议使用Add()方法,其它场合可以使用AddWithValue()简化代码编写量。"

 

效率的话有说这个高的也又说那个高的,不太清楚

据网上说Parameters.AddWithValue在传入数据是DataTime的时候会出错。

我觉得为了保险还是用Add比较好。

 

下面贴一段我自己用Add的代码,这里先放到一个sqlparameter对象里再一起加入。

 

代码
try
  {
    conn = new SqlConnection(ConfigurationManager.ConnectionStrings[ " nd_dataConnectionString " ].ConnectionString); // 取连接字符串,建立连接
    conn.Open();
    comm
= new SqlCommand( " update nd_cn set name=@name,text=@text where id= " + textid, conn);

    SqlParameter[] pars
= { new SqlParameter( " @name " ,SqlDbType.NVarChar, 50 ),
                   new SqlParameter( " @text " ,SqlDbType.Text)};
    pars[
0 ].Value = TextBox1.Text;
    pars[
1 ].Value = tbContent.Text;
    
foreach (SqlParameter parameter in pars)
    {
      comm.Parameters.Add(parameter);
    }
    comm.ExecuteNonQuery();

  }
  
catch (SqlException e1)
  {
    Response.Write(e1.ToString());
  }
  
finally
  {
    conn.Close();
  }

 

 

 

里面的SqlDbType要区分大小写,具体有哪些的话请参看msdn中表格:

  
BigIntInt64.64 位带符号整数。
BinaryByte 类型的 Array。二进制数据的固定长度流,范围在 1 到 8,000 个字节之间。
BitBoolean.无符号数值,可以是 0、1 或 null。
CharString.非 Unicode 字符的固定长度流,范围�� 1 到 8,000 个字符之间。
DateTimeDateTime.日期和时间数据,值范围从 1753 年 1 月 1 日到 9999 年 12 月 31 日,精度为 3.33 毫秒。
DecimalDecimal.固定精度和小数位数数值,在 -10 38 -1 和 10 38 -1 之间。
FloatDouble.-1.79E +308 到 1.79E +308 范围内的浮点数。
ImageByte 类型的 Array。二进制数据的可变长度流,范围在 0 到 2 31 -1(即 2,147,483,647)字节之间。
IntInt32.32 位带符号整数。
MoneyDecimal.货币值,范围在 -2 63(即 -922,337,203,685,477.5808)到 2 63 -1(即 +922,337,203,685,477.5807)之间,精度为千分之十个货币单位。
NCharString.Unicode 字符的固定长度流,范围在 1 到 4,000 个字符之间。
NTextString.Unicode 数据的可变长度流,最大长度为 2 30 - 1(即 1,073,741,823)个字符。
NVarCharString.Unicode 字符的可变长度流,范围在 1 到 4,000 个字符之间。如果字符串大于 4,000 个字符,隐式转换会失败。在使用比 4,000 个字符更长的字符串时,请显式设置对象。
RealSingle.-3.40E +38 到 3.40E +38 范围内的浮点数。
UniqueIdentifierGuid.全局唯一标识符(或 GUID)。
SmallDateTimeDateTime.日期和时间数据,值范围从 1900 年 1 月 1 日到 2079 年 6 月 6 日,精度为 1 分钟。
SmallIntInt16.16 位的带符号整数。
SmallMoneyDecimal.货币值,范围在 -214,748.3648 到 +214,748.3647 之间,精度为千分之十个货币单位。
TextString.非 Unicode 数据的可变长度流,最大长度为 2 31 -1(即 2,147,483,647)个字符。
TimestampByte 类型的 Array。自动生成的二进制数字,它们保证在数据库中是唯一的。timestamp 通常用作为表行添加版本戳的机制。存储大小为 8 字节。
TinyIntByte.8 位无符号整数。
VarBinaryByte 类型的 Array。二进制数据的可变长度流,范围在 1 到 8,000 个字节之间。如果字节数组大于 8,000 个字节,隐式转换会失败。在使用比 8,000 个字节大的字节数组时,请显式设置对象。
VarCharString.非 Unicode 字符的可变长度流,范围在 1 到 8,000 个字符之间。
VariantObject.特殊数据类型,可以包含数值、字符串、二进制或日期数据,以及 SQL Server 值 Empty 和 Null,后两个值在未声明其他类型的情况下采用。
XmlXML 值。使用 GetValue 方法或 Value 属性获取字符串形式的 XML,或通过调用 CreateReader 方法获取 XmlReader 形式的 XML。
UdtSQL Server 2005 用户定义的类型 (UDT)。
Structured指定表值参数中包含的构造数据的特殊数据类型。
Date日期数据,值范围从公元 1 年 1 月 1 日到公元 9999 年 12 月 31 日。
Time基于 24 小时制的时间数据。时间值范围从 00:00:00 到 23:59:59.9999999,精度为 100 毫微秒。对应于 SQL Server time 值。
DateTime2日期和时间数据。日期值范围从公元 1 年 1 月 1 日到公元 9999 年 12 月 31 日。时间值范围从 00:00:00 到 23:59:59.9999999,精度为 100 毫微秒。
DateTimeOffset显示时区的日期和时间数据。日期值范围从公元 1 年 1 月 1 日到公元 9999 年 12 月 31 日。时间值范围从 00:00:00 到 23:59:59.9999999,精度为 100 毫微秒。时区值范围从 -14:00 到 +14:00。

 

最后再贴一段类似的代码提供比较

 

代码
try
  {
    openCon();
    
// sTran = con.BeginTransaction(); // 事务对象
    cmd = new SqlCommand(sql,con);
    
// cmd.Transaction = sTran; // 执行事务
    
// try
    
// {
    
// 调用存储过程
    cmd.CommandType = CommandType.StoredProcedure;
    
// 添加参数
    SqlParameter[] pars = { new SqlParameter( " @FartherTypeID " ,SqlDbType.Int),
new SqlParameter( " @DetailTypeID " ,SqlDbType.Int),
new SqlParameter( " @LevelTypeID " ,SqlDbType.Int),
new SqlParameter( " @BookName " ,SqlDbType.VarChar, 50 ),
new SqlParameter( " @MarketPrice " ,SqlDbType.Money),
new SqlParameter( " @MenberPrice " ,SqlDbType.Money),
new SqlParameter( " @Rebate " ,SqlDbType.Float),
new SqlParameter( " @BookWriter " ,SqlDbType.VarChar, 100 ),
new SqlParameter( " @BookConcern " ,SqlDbType.VarChar, 50 ),
new SqlParameter( " @ISBN " ,SqlDbType.VarChar, 20 ),
new SqlParameter( " @BookIntroduce " ,SqlDbType.VarChar, 5000 ),
new SqlParameter( " @AddDateTime " ,SqlDbType.DateTime),
new SqlParameter( " @BookPicture " ,SqlDbType.VarChar, 200 ),
};
    
foreach (SqlParameter parameter in pars)
    {
      cmd.Parameters.Add(parameter);
   }
    
return cmd.ExecuteNonQuery();

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值