如何从查询中获取结果,即使在command.executeReader()期间发生SQL异常

本文关键字:executeReader 异常 SQL command 查询 获取 结果 | 更新日期: 2023-09-27 17:49:32

我有这段代码,有时工作,有时不工作。正在执行的查询不是由我自己编写的,但我被告知,我所要做的就是对数据库运行它以获得我需要的结果。下面是我的代码:

try {
  using (SqlDataReader dr = cmd.ExecuteReader()) {
    while (dr.Read()) {
      try {
        list.Add(dr.GetString(3) + " " + dr.GetInt32(4).ToString() + " " + dr.GetString(5) + " " + dr.GetDecimal(8).ToString());
      } catch (Exception e) {
        list.Add("fail");
      }
    }
  }
} catch (SqlException sqlException) {
  Debug.WriteLine(sqlException.Message);
}

我有时收到的错误是我不能删除表,因为我没有权限或表不存在。其他时候,查询执行没有任何问题,我能够检索和存储我的结果在一个列表。

当我在SQL Server 2008中运行查询时,有时我确实会得到错误,但结果仍然显示,并且是我所期望的。所以我的问题是:我怎样才能抓住这些结果,而不管错误似乎随时出现感觉?

这是给我带来麻烦的一小段查询:

IF  EXISTS (SELECT * from tempdb..sysobjects where name like '#TABLE%')  
DROP #TABLE

在我正在运行的查询中有许多这样的if语句,并且无法预测哪一个会导致错误。所以我现在所做的就是在一个try-catch块中包围DROP #TABLE,这样至少我仍然可以在我的silverlight程序中检索结果。我将得到我的上级,问他为什么查询是自发返回这些错误..

如何从查询中获取结果,即使在command.executeReader()期间发生SQL异常

EDIT

没关系,我知道问题所在了。我忘了临时表的名称是附加额外的字符来防止不同进程之间的命名冲突的(例如#TABLE___...___0000000064E2)。

我的猜测是,在某些情况下,存储过程正在创建一个名为"# table"的临时表,而您发布的SQL代码是为了执行清理。当它自己运行时,这可能工作得很好。

当存储过程由多个客户端同时运行时,或者如果前面的一个查询以某种方式未能执行清理(可能是由于中途出现错误),问题可能开始出现。在这种情况下,会创建一个误报(存储进程认为清理是必要的,但实际上它看到的是另一个进程创建的临时表)。然后你会得到错误,因为没有与当前进程相关联的#TABLE。

无论如何,在try-catch中包装语句似乎是一种体面的方法。一个更好的方法是彻底检查你的代码,也许设置某种标志来帮助指示清理是必要的,或者使用一个公共表和某种事务键(删除与当前事务相关的所有记录,而不是删除表)。

您可能还想考虑使用表变量而不是临时表。

:
http://social.msdn.microsoft.com/Forums/en-US/sqltools/thread/02337dd5-5cfd-40d8-b529-12dc557d6a7e/

或者,您也可以考虑完全跳过DROP语句:
临时表作用域?


回答你原来的问题,我不知道任何方式检索结果从SQL查询一旦它抛出了一个异常,而不是通过。net程序集,无论如何。SQL Server Management Studio使用了一些重型的、定制的api,这些api可能不值得你花时间去学习和使用。


忽略以下
(保留供参考)

如果可以,尝试将SQL查询更改为

IF  EXISTS (SELECT * from tempdb..sysobjects where name = '#TABLE')
DROP #TABLE

(change like '#TABLE%' to = '#TABLE')

like语句没有任何意义…如果有其他表以"#TABLE"开头也没关系…你只需要知道是否有一个名为的表正好是 "# table "。

我猜这是其中一种情况,逻辑被改变了,但只是一半,可能是两个不同的人。