现在的位置: 首页 > 综合 > 正文

asp.net 用parameter对象更新数据

2012年08月15日 ⁄ 综合 ⁄ 共 6410字 ⁄ 字号 评论关闭

  部分摘自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中表格:

说明
由 XNA Framework 提供支持 BigInt Int64. 64 位带符号整数。
由 XNA Framework 提供支持 Binary Byte 类型的 Array 二进制数据的固定长度流,范围在 1 到 8,000 个字节之间。
由 XNA Framework 提供支持 Bit Boolean. 无符号数值,可以是 0、1 或 null
由 XNA Framework 提供支持 Char String. 非 Unicode 字符的固定长度流,范围�� 1 到 8,000 个字符之间。
由 XNA Framework 提供支持 DateTime DateTime. 日期和时间数据,值范围从 1753 年 1 月 1 日到 9999 年 12 月 31 日,精度为 3.33 毫秒。
由 XNA Framework 提供支持 Decimal Decimal. 固定精度和小数位数数值,在 -10 38 -1 和 10 38 -1 之间。
由 XNA Framework 提供支持 Float Double. -1.79E +308 到 1.79E +308 范围内的浮点数。
由 XNA Framework 提供支持 Image Byte 类型的 Array 二进制数据的可变长度流,范围在 0 到 2 31 -1(即 2,147,483,647)字节之间。
由 XNA Framework 提供支持 Int Int32. 32 位带符号整数。
由 XNA Framework 提供支持 Money Decimal. 货币值,范围在 -2 63(即 -922,337,203,685,477.5808)到 2 63 -1(即 +922,337,203,685,477.5807)之间,精度为千分之十个货币单位。
由 XNA Framework 提供支持 NChar String. Unicode 字符的固定长度流,范围在 1 到 4,000 个字符之间。
由 XNA Framework 提供支持 NText String. Unicode 数据的可变长度流,最大长度为 2 30 - 1(即 1,073,741,823)个字符。
由 XNA Framework 提供支持 NVarChar String. Unicode 字符的可变长度流,范围在 1 到 4,000 个字符之间。 如果字符串大于 4,000 个字符,隐式转换会失败。 在使用比 4,000 个字符更长的字符串时,请显式设置对象。
由 XNA Framework 提供支持 Real Single. -3.40E +38 到 3.40E +38 范围内的浮点数。
由 XNA Framework 提供支持 UniqueIdentifier Guid. 全局唯一标识符(或 GUID)。
由 XNA Framework 提供支持 SmallDateTime DateTime. 日期和时间数据,值范围从 1900 年 1 月 1 日到 2079 年 6 月 6 日,精度为 1 分钟。
由 XNA Framework 提供支持 SmallInt Int16. 16 位的带符号整数。
由 XNA Framework 提供支持 SmallMoney Decimal. 货币值,范围在 -214,748.3648 到 +214,748.3647 之间,精度为千分之十个货币单位。
由 XNA Framework 提供支持 Text String. 非 Unicode 数据的可变长度流,最大长度为 2 31 -1(即 2,147,483,647)个字符。
由 XNA Framework 提供支持 Timestamp Byte 类型的 Array 自动生成的二进制数字,它们保证在数据库中是唯一的。 timestamp 通常用作为表行添加版本戳的机制。 存储大小为 8 字节。
由 XNA Framework 提供支持 TinyInt Byte. 8 位无符号整数。
由 XNA Framework 提供支持 VarBinary Byte 类型的 Array 二进制数据的可变长度流,范围在 1 到 8,000 个字节之间。 如果字节数组大于 8,000 个字节,隐式转换会失败。 在使用比 8,000 个字节大的字节数组时,请显式设置对象。
由 XNA Framework 提供支持 VarChar String. 非 Unicode 字符的可变长度流,范围在 1 到 8,000 个字符之间。
由 XNA Framework 提供支持 Variant Object. 特殊数据类型,可以包含数值、字符串、二进制或日期数据,以及 SQL Server 值 Empty 和 Null,后两个值在未声明其他类型的情况下采用。
由 XNA Framework 提供支持 Xml XML 值。 使用 GetValue 方法或 Value 属性获取字符串形式的 XML,或通过调用 CreateReader 方法获取 XmlReader 形式的 XML。
由 XNA Framework 提供支持 Udt SQL Server 2005 用户定义的类型 (UDT)。
由 XNA Framework 提供支持 Structured 指定表值参数中包含的构造数据的特殊数据类型。
由 XNA Framework 提供支持 Date 日期数据,值范围从公元 1 年 1 月 1 日到公元 9999 年 12 月 31 日。
由 XNA Framework 提供支持 Time 基于 24 小时制的时间数据。 时间值范围从 00:00:00 到 23:59:59.9999999,精度为 100 毫微秒。 对应于 SQL Server time 值。
由 XNA Framework 提供支持 DateTime2 日期和时间数据。 日期值范围从公元 1 年 1 月 1 日到公元 9999 年 12 月 31 日。 时间值范围从 00:00:00 到 23:59:59.9999999,精度为 100 毫微秒。
由 XNA Framework 提供支持 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();  

}

 

看看麻烦一点 其实用起来还好的

抱歉!评论已关闭.