【问题标题】:The affected rows are 2 while there is only one item in SQL Server受影响的行是 2,而 SQL Server 中只有一项
【发布时间】:2022-01-16 16:27:48
【问题描述】:

使用C#代码删除SQL Server中的行时,返回的影响行数为2,但表中只有一项。这是代码。

            int result = -1;
            using (SqlConnection sqlConnection = new SqlConnection(AppConfiguration.ConnectionStringIguide))
            {
                string sql = string.Format("delete from atblOrders where OrderID='{0}'", orderId);
                using (SqlCommand sqlCommand = new SqlCommand())
                {
                    sqlCommand.Connection = sqlConnection;
                    sqlCommand.CommandText = sql;
                    sqlCommand.CommandType = CommandType.Text;
                    sqlConnection.Open();
                    result = sqlCommand.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

我将 SQL 复制到 SQL Server Management Studio 并运行 SQL。它打印出两行受影响的 1 行。

(1 行受影响) (1 行受影响) 完成时间:2021-12-13T13:53:52.0466180+08:00

如果我使用具有相同 id 的 select 查询,它只会返回一项。那么,为什么删除时会影响两行?

【问题讨论】:

  • 表上是否有删除另一个表中记录的DELETE触发器?
  • 我同意它很可能是一个 DELETE 触发器,但这个触发器可能会插入、更新或删除。如果是出于审计跟踪目的,它很可能是插入!
  • @juergend。是的。我使用select * from sysobjects a INNER JOIN sys.triggers b ON b.object_id = a.id INNER JOIN syscomments c ON c.id = a.id WHERE a.xtype = 'tr'检查触发器,我找到了一个与这张表相关的。

标签: c# sql-server


【解决方案1】:

正如 cmets 中所述,这很可能是因为为此表定义了一个触发器(forinstead of)删除。

但是,这不是您代码中的主要问题。 您的代码中的主要问题是它容易受到 SQL 注入攻击,因为您将字符串连接到 SQL 中而不是使用参数。

有关更多信息,您可以阅读我题为 Back to basics: SQL Injection 的博文,以及 Sandy 的问题及其在 stackoverflow 上的答案 - Why do we always prefer using parameters in SQL statements?

【讨论】:

  • 虽然我大体上同意养成在所有情况下都使用参数的好习惯,但我觉得公平地指出,由 OP 编写的代码实际上并不容易受到 SQL 注入的影响。 C# 是一种强类型语言。假设 orderId 是一个 int(使用 string.Format 的自然假设),那么在运行时任何将有害 SQL 放入 orderId 的尝试都会失败。
  • @JonathanWillcock。是的,订单 ID 是一个整数。好眼睛。反正使用参数是个好习惯。
  • @JonathanWillcock 另一方面,where OrderID='{0}' 似乎暗示订单 id 可能不是 int (这是我在写答案时考虑过的事情之一) - 但我同意如果您达到了可以使用 int 执行 sql 注入攻击的地步,那可能是您最不担心的事情。欲了解更多信息,请阅读 Jon Skeet 题为 THE BOBBYTABLES CULTURE 的博文
  • @ZoharPeled 更令我不安的是 OrderId (列)不是 int 而不是 orderId (变量)的含义。将数字作为字符串存储在数据库中是一个严重的失败。当然它仍然可能是一个 int 并且 OP 正在让 SQL Server 进行不必要的强制转换。
  • @JonathanWillcock 不必要的强制转换确实是一个问题,但这不是一个很大的问题。以错误的数据类型存储数据会对数据库产生最严重的影响。 Aaron Bertrand 在Bad Habits to Kick : Choosing the wrong data type 中写到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-24
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
相关资源
最近更新 更多