【问题标题】:ExecuteNonQuery update does not store changeExecuteNonQuery 更新不存储更改
【发布时间】:2014-03-04 21:27:22
【问题描述】:

我正在尝试使用 ExecuteNonQuery() 更新数据库中的某些字段。

尝试更新时,我没有收到任何错误或警告,它返回一个受影响的行数。

问题是,我只能针对当前请求,查看更改。如果我重新加载页面或通过 SMSS,更改不会显示在数据库中。

这是一个小代码。

    string Sql = "UPDATE AccessUser SET [" + Field + "] = '" + Database.SqlEscapeInjection(Value) + "' WHERE AccessUserID = " + User.ID;
    Response.Write("<br>" + Sql + "<br>");

    IDataReader Se = Database.CreateDataReader("SELECT * FROM AccessUser WHERE AccessUserID = " + User.ID);
    while (Se.Read())
    {
        Response.Write((string)Se[Field] + "<br>");
    }

    int affectedrows = Database.ExecuteNonQuery(Sql, Database.CreateConnection());

    Response.Write("<br>NUMMER: " + affectedrows + "<br>");
    IDataReader S = Database.CreateDataReader("SELECT * FROM AccessUser WHERE AccessUserID = " + User.ID);
   while (S.Read())
   {
       Response.Write((string)S[Field] + "<br>");
   }

如您所见,我首先输出当前值,然后运行更新查询,然后再次输出该值。 (必须通知你,我通常使用绑定参数,但为了调试,我把它们扔掉了。)

结果如下: 乔纳斯 数量:1 米克尔

当我刷新页面或查看数据库时,该行并没有改变。 该怎么办? :D

编辑: 系统“Dynamicweb-CMS”的文档指出它不是事务性的: http://developer.dynamicweb-cms.com/api8/Dynamicweb~Dynamicweb.Database~ExecuteNonQuery(String,IDbConnection,IDbTransaction).html 我应该能够做到,就像我实际上所做的那样。奇怪的东西。

编辑 2: 为了取悦那些有“绑定参数强迫症”的人

    using (IDbConnection connection = Database.CreateConnection())
    {
        IDbCommand command = connection.CreateCommand();
        command.CommandText = "UPDATE AccessUser SET [" + Field + "] = @ParamValue WHERE AccessUserID = @UserId";
        Database.AddStringParam(command, "@ParamValue", Value);
        Database.AddInt32Param(command, "@UserId", User.ID);

        //Execute command
        command.ExecuteNonQuery();
        connection.Close();
    }

与其他查询方法的结果相同。

也试过了。什么都没有发生。

   using (SqlConnection cn = new SqlConnection(SQLString))
        {
            SqlTransaction Trans;
            try
            {

                cn.Open();
                Trans = cn.BeginTransaction();
                IDbCommand command = cn.CreateCommand();
                command.Transaction = Trans;
                command.CommandText = "UPDATE AccessUser SET [" + Field + "] = @ParamValue WHERE AccessUserID = @UserId";
                Database.AddStringParam(command, "@ParamValue", Value);
                Database.AddInt32Param(command, "@UserId", User.ID);

                //Execute command
                int affectedRecords = command.ExecuteNonQuery();
                Response.Write("<br>NUMMER: " + affectedRecords + "<br>");
                Response.Write(cn.ServerVersion );
                Trans.Commit();
                cn.Close();
            }
            catch (Exception e)
            {
                Response.Write("<span style='color:red;'>" + e.Message + "</span>");
            }
        };

我运行分析器并查看更新语句。更新语句后,发送如下

Audit Login:
-- network protocol: LPC
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed

按照我的逻辑,这告诉我更改已提交。 现在,然而,之后,我得到了这个(不得不削减它,Stackoverflow 不喜欢它)

RPC:Completed:
exec sp_executesql N'UPDATE [AccessUser] SET [AccessUserUpdatedOn] = @p1 WHERE (([AccessUserID] = @p2) AND ((@p3 = 1 AND [AccessUserParentID] IS NULL) OR ([AccessUserParentID] = @p4)) AND ((@p5 = 1 AND [AccessUserUserName] IS NULL) OR ([AccessUserUserName] = @p6)) AND ((@p7 = 1 AND [AccessUserPassword] IS NULL) OR ([AccessUserPassword] = @p8)) AND ((@p9 = 1 AND [AccessUserName] IS NULL) OR ([AccessUserName] = @p10)) AND ((@p11 = 1 AND [AccessUserDepartment] IS NULL) OR ([AccessUserDepartment] = @p12)) AND ((@p13 = 1 AND [AccessUserEmail] IS NULL) OR ([AccessUserEmail] = @p14)) AND ((@p15 = 1 AND [AccessUserPhone] IS NULL) OR ([AccessUserPhone] = @p16)) AND ((@p17 = 1 AND [AccessUserFax] IS NULL) OR ([AccessUserFax] = @p18)) AND ((@p19 = 1 AND [AccessUserGroups] IS NULL) OR ([AccessUserGroups] = @p20)) AND ((@p21 = 1 AND [AccessUserType] IS NULL) OR ([AccessUserType] = @p22)) AND ((@p23 = 1 AND [AccessUserValidFrom] IS NULL) OR ([AccessUserValidFrom] = @p24)) AND ((@p25 = 1 AND [AccessUserValidTo] IS NULL) OR ([AccessUserValidTo] = @p26)) AND ((@p27 = 1 AND 

-并再次将内容更新回原始内容。 我将如何检查这是否是某种事务回滚?或者别的什么。 请原谅英语。

【问题讨论】:

  • 请使用parameterized SQL
  • 嗨 Albireo - 正如问题中所述,我通常使用绑定参数,在这种情况下,它也不起作用。此语法纯粹用于调试目的。
  • 添加了带有绑定参数的示例,这导致完全相同的行为。
  • 使用 SQL Server 分析器检查查询是否实际在目标数据库上执行并检查是否有任何 BEGIN TRAN 调用。
  • 在上一个示例中,当 ExecuteNonQuery 完成时,“affectedRecords”的值是多少?这将有助于调试。

标签: c# sql-server executenonquery


【解决方案1】:

您可能正在使用事务。当您使用事务时,您必须在完成后提交事务,否则它将自动回滚 - 因此,在您的情况下,您进行更新,没有错误。然后您使用相同的 SQL 连接进行检查,一切看起来都很好。然后在某个时候离开事务范围,事务会自动回滚,恢复数据库中的更改。

【讨论】:

  • 可能您有一个TransactionScope() 将其包装在更高级别?
  • @Jonasm TransactionScope 是一个好主意,它也可能处于更高的级别 - 您正在使用 ASP.NET,它可以在整个 Web 服务方法上拥有事务范围,并且可能甚至页面本身。事务系统实际上是独立于数据库的,它甚至可以处理许多其他事情而不仅仅是数据库。还有一些方法可以使用属性(TransactionAttribute 和其他)来控制它。尝试msdn.microsoft.com/en-us/library/3b0dwf12(v=vs.80).aspx 获取参考。
  • @Jonasm 这很奇怪......是否有可能其他人正在同时修改表格?也许某个地方有一个后台工作人员,或者一个触发器或其他什么东西,它正在改变你手中的价值?如果可以的话,尝试使用 SQL Profiler 或其他工具来观察所有发送到服务器的 SQL 命令。
  • 最后一件事 - 寻找一个而不是更新触发器。
  • @Jonasm 好的,这听起来不像 MS SQL 事务回滚(它可能应该是“回滚传输启动”或类似的东西)。相反,您似乎真的要再次手动更新该行。这可能是由于某些 O/RM 尝试将更改同步到数据库,或者正如 StuartLC 建议的那样,更新触发器(尽管我不确定它是否会出现在 SQL 分析器中)。 SQL 探查器行中应该有一些连接 ID - 它是否为两个更新显示相同的值?如果是,那可能微弱地暗示这两个更新是通过同一个连接完成的。
猜你喜欢
  • 1970-01-01
  • 2019-09-01
  • 2021-02-24
  • 2018-06-14
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多