2010-06-07 96 views
1

我有以下形式的简单的SQL插入语句:为什么“插入(...)值(...)”不能插入新行?

insert into MyTable (...) values (...) 

它被反复用于插入行,通常按预期工作。它向MyTable插入正好1行,这也是Delphi语句AffectedRows返回的值:= myInsertADOQuery.ExecSQL。

经过一段时间后,出现了临时的网络连接问题。因此,同一应用程序的其他线程感知到EOleExceptions(连接失败,-2147467259 =未指定的错误)。后来,网络连接重新建立,这些线程重新连接,并没有问题。

但是,负责执行上述插入语句的线程没有察觉到连接问题(没有例外) - 可能它在网络关闭时根本没有执行。但是,在网络连接问题之后,myInsertADOQuery.ExecSQL总是返回0,并且没有行被插入到MyTable中。应用程序重新启动后,插入语句按预期再次运行。

对于SQL Server,是否有任何定义的情况下,像上面的插入语句不会插入一行并返回0作为受影响的行数?主键是自动生成的GUID。没有唯一或检查约束(无论如何,这应该导致异常,而不是插入一行)。

是否有任何已知的ADO错误(Provider = SQLOLEDB.1)?

对此行为的任何其他解释?

谢谢, N。

+0

您是否使用SQL Server附带的SQL事件探查器工具跟踪结果?在这个问题上的第一个答案有一个视频解释如何做到这一点:http://stackoverflow.com/questions/504326/trace-file-how-to-use-it – 2010-06-07 12:47:02

+0

不,我没有。感谢提示。如果它再次发生,我会试一试。 – nang 2010-06-07 14:33:35

回答

1

如果你想插入值违反

  • CHECK约束
  • 一个外键关系
  • NOT NULL约束
  • UNIQUE约束

或任何其他约束,那么行将不会被插入。

+0

谢谢!真正。但是,我会期待一个例外,而不是默默地不插入一行。但除此之外,没有这样的限制。 – nang 2010-06-07 11:58:17

1

你使用交易吗?也许你的应用程序没有autocommit?如果交易中出现错误,某些司机不会提交数据。

+0

谢谢。没有使用明确的交易,但自动提交。如果我使用事务,ExecSQL应该返回1为受影响的行数,不是吗? – nang 2010-06-07 11:59:46

2

如果你没有任何异常,则:

  1. 当表具有触发器没有SET NOCOUNT ON,然后实际操作(INSERT/UPDATE/DELETE)可以成功完成,但一些受影响的记录可能会返回为0.
  2. 根据当前会话中的事务活动,其他会话可能看不到当前会话所做的更改。但目前的会议将看到自己的变化和一些受影响的记录将(可能)不是0.

所以,确切的答案可能取决于您的表DDL(+触发器,如果​​有的话),以及如何你是检查插入的行。

+0

谢谢。 1.没有使用触发器。 2.当前会话不会观察插入的行,也不会看到外部会话。我通过My​​Query.ExecSQL的返回值来检查插入行的数量。此外,我通过SQL Management Studio检查了表的新行 - 没有新行。此外,在一般情况下,一切正常。所以我想在ADO /提供程序级别发生一些奇怪的事情,而不是实际在SQL/SQL Server级别。 – nang 2010-06-07 12:05:47

+0

你能重现你的问题吗? – 2010-06-07 14:16:56

+0

一开始一切正常。然后这个问题第一次出现了。从那以后,这是永久的,直到我重新启动我的应用程序。从那以后,我无法再现它。 – nang 2010-06-07 14:32:50

2

看起来您的插入线程在静默中丢失了连接,并且没有检查它是否需要自动重新连接,但是在插入时保持排队而不实际发送它们。
我会在一个小型的独立应用程序中隔离这些代码以进行调试,并查看当您自愿断开网络然后重新连接时它的行为。
如果您发现“吞食”异常,或者某些代码忽略检查成功/失败,我不会感到惊讶。
希望它有帮助...

+0

听起来很合理。我还没有描述:当我关闭应用程序时,报告了一些内存泄漏,包括〜45 TADOCommand和〜45 TADOQuery实例。我只是想知道异常可能被吞噬了,绝对不在我的用户代码中。在正常情况下,一旦连接中断,所有后续尝试执行异常的查询结果。 – nang 2010-06-08 10:25:40