C# SQL Server:找不到句柄为x的准备语句

C# SQL Server:找不到句柄为x的准备语句,c#,sql-server,sql-server-2005,sql-server-2005-express,C#,Sql Server,Sql Server 2005,Sql Server 2005 Express,最近,我们的QA团队报告了我们的一个应用程序中的一个非常有趣的错误。我们的应用程序是一个基于C#.Net 3.5 SP1的应用程序,与SQL Server 2005 Express Edition数据库交互 通过设计,开发应用程序以检测数据库脱机情况,如果是,则等待数据库联机(通过及时尝试连接),一旦联机,则重新连接并恢复功能 我们的QA团队所做的是,当应用程序从数据库检索大量数据时,停止数据库服务器,等待一段时间,然后重新启动数据库。一旦数据库重新启动,应用程序将重新连接到数据库,不会出现任何

最近,我们的QA团队报告了我们的一个应用程序中的一个非常有趣的错误。我们的应用程序是一个基于C#.Net 3.5 SP1的应用程序,与SQL Server 2005 Express Edition数据库交互

通过设计,开发应用程序以检测数据库脱机情况,如果是,则等待数据库联机(通过及时尝试连接),一旦联机,则重新连接并恢复功能

我们的QA团队所做的是,当应用程序从数据库检索大量数据时,停止数据库服务器,等待一段时间,然后重新启动数据库。一旦数据库重新启动,应用程序将重新连接到数据库,不会出现任何问题,但它开始连续报告异常“找不到具有句柄x的准备好的语句”(x是某个数字)

我们的应用程序正在使用prepared语句,并且已经设计好在应用程序重新连接到数据库时对所有SqlCommand对象再次调用Prepare()方法。比如说,

在应用程序启动时

    SqlCommand _commandA = connection.CreateCommand();
    _commandA.CommandText = @"SELECT COMPANYNAME FROM TBCOMPANY WHERE ID = @ID";
    _commandA.CommandType = CommandType.Text;
    SqlParameter _paramA = _commandA.CreateParameter();
    _paramA.ParameterName = "@ID";
    _paramA.SqlDbType = SqlDbType.Int;
    _paramA.Direction = ParameterDirection.Input;
    _paramA.Size = 0;
    _commandA.Parameters.Add(_paramA);
    _commandA.Prepare();
之后,我们在这个_commandA上使用executeReader(),在应用程序的每个周期中使用不同的@ID参数值

一旦应用程序检测到数据库脱机并重新联机,在重新连接到数据库时,应用程序仅执行

    _commandA.Prepare();
我们又注意到两件奇怪的事。 1.代码中的CommandType.Text-type命令会出现上述情况。我们的应用程序也使用相同的精确逻辑来调用存储过程,但我们从未发现存储过程存在此问题。 2.到目前为止,无论我们在VisualStudio的调试模式下尝试了多少种不同的方法,我们都无法重现这个问题


提前谢谢

当您调用“command.Prepare”时,服务器缓存查询计划。该错误表明,当您再次调用“准备”时,它找不到此缓存的查询计划。尝试创建一个新的“SqlCommand”实例并对其调用查询。我以前遇到过这个异常,当服务器刷新缓存时,它会自行修复。我怀疑客户端是否可以通过编程方式解决此问题。

当您调用“command.Prepare”时,服务器会缓存查询计划。该错误表明,当您再次调用“准备”时,它找不到此缓存的查询计划。尝试创建一个新的“SqlCommand”实例并对其调用查询。我以前遇到过这个异常,当服务器刷新缓存时,它会自行修复。我怀疑客户端是否可以通过编程方式解决此问题。

我想,通过近3天的提问和近20个问题视图和1个答案,我不得不得出结论,这不是我们可以用SQL server尝试的方式处理的情况

在应用程序中缓解此问题的最佳方法是在应用程序检测到数据库联机后再次重新创建SqlCommand对象实例

我们在应用程序中进行了更改,我们的QA团队对这次修改感到高兴,因为它为他们报告的问题提供了最佳(或可能是唯一)修复


最后感谢所有看过并回答问题的人

我想,通过近3天的提问和近20个问题视图和1个答案,我必须得出结论,这不是一个我们可以用SQL server尝试的方式处理的场景

在应用程序中缓解此问题的最佳方法是在应用程序检测到数据库联机后再次重新创建SqlCommand对象实例

我们在应用程序中进行了更改,我们的QA团队对这次修改感到高兴,因为它为他们报告的问题提供了最佳(或可能是唯一)修复


最后感谢所有看过并回答问题的人

这不一定与您的问题完全相关,但我已经花了几天时间试图修复应用程序中的同一错误消息,因此我将发布此消息。我们有一个Java应用程序,它使用C3P0连接池JTDS驱动程序连接到SQL Server数据库


我们在C3P0连接池中禁用了语句缓存,但在驱动程序级别上没有这样做。向我们的连接URL添加maxStatements=0停止了驱动程序缓存语句,并修复了错误。

这不一定与您的问题完全相关,但我正在发布此消息,因为我花了几天时间试图修复应用程序中的相同错误消息。我们有一个Java应用程序,它使用C3P0连接池JTDS驱动程序连接到SQL Server数据库


我们在C3P0连接池中禁用了语句缓存,但在驱动程序级别上没有这样做。向我们的连接URL添加maxStatements=0停止了驱动程序缓存语句,并修复了错误。

感谢您的响应。我还怀疑我们是否可以做些什么来修复这个问题,而不是在重新连接到数据库时重新创建SqlCommand实例。我们已经试过了,它当然是有效的。但是,我们在基于Oracle 11g R2数据库的中央数据中心应用程序中尝试了这一点,在该应用程序中,关闭并重新启动数据库后仅调用Prepare()的相同逻辑不会出现任何问题。这就是为什么我们想知道为什么它不能在SQLServer中工作。也许“Oracle+ODAC”比“SQL server+SQL客户端”更聪明……:)这是一个特定于Sql Server的错误。这不会发生在Oracle数据库上。感谢您的回复。我还怀疑我们是否可以做些什么来修复这个问题,而不是在重新连接到数据库时重新创建SqlCommand实例。我们已经试过了,它当然是有效的。然而,我们在我们的中央数据中心应用程序中尝试了这一点,该应用程序基于Oracle 11g R2数据库,在该数据库中,只有calli使用了相同的逻辑