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

时间:2012-12-27 00:06:35

标签: c# silverlight

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

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程序中检索结果。我会更高兴地问他为什么查询会自发地返回这些错误..

1 个答案:

答案 0 :(得分:1)

修改

没关系,我看到了问题。我忘记了临时表名附加了其他字符,以防止不同进程之间的命名冲突(例如#TABLE___...___0000000064E2)。

我的猜测是存储过程在某些情况下创建一个名为“#TABLE”的临时表,并且您发布的SQL代码位用于执行清理。单独运行时,这可能正常。

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

无论如何,将语句包装在try-catch中似乎是一种不错的方法。更好的方法是涉及对代码进行大修,可能设置某种标志以帮助指示需要清理或使用公共表和某种事务键(删除与当前事务关联的所有记录,而不是删除表)。

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

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

或者,您也可以考虑完全跳过DROP声明:
Temporary Table Scope?


要回答您的原始问题,我不知道有什么方法可以在SQL查询抛出异常后从SQL查询中检索结果,而不是通过.NET程序集。 SQL Server Management Studio使用一些重型的定制API,这些API可能不值得您学习和使用。


忽略以下
(保留供参考)

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

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

(将like '#TABLE%'更改为= '#TABLE'

like语句没有任何意义......如果有其他表以“#TABLE”开始并不重要......你只想知道如果有一个名为的表“#TABLE”。

我的猜测是,这是逻辑改变的情况之一,但只有一半,可能是两个不同的人。