我有这段代码有时有效,有时却无效。正在执行的查询还没有由我自己编写,但我被告知我所要做的就是对数据库运行它以获得我需要的结果。这是我的代码:
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程序中检索结果。我会更高兴地问他为什么查询会自发地返回这些错误..
答案 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”。
我的猜测是,这是逻辑改变的情况之一,但只有一半,可能是两个不同的人。