Java PreparedStatement在SQL Server上的prepareStatement上执行

Java PreparedStatement在SQL Server上的prepareStatement上执行,java,sql-server,jdbc,Java,Sql Server,Jdbc,我们有一个类似于以下内容的Java代码: PreparedStatement stmt = connection.prepareStatement("drop login tmp"); int result = stmt.executeUpdate(); 当通过调试器运行时,我们的SQL语句似乎是在第一行执行之后,甚至在第二行执行之前执行的。当执行第二行时,将再次执行drop SQL,并导致错误,因为用户名tmp不再存在 这只会发生在SQL Server上,而不会发生在Oracle和Postg

我们有一个类似于以下内容的Java代码:

PreparedStatement stmt = connection.prepareStatement("drop login tmp");
int result = stmt.executeUpdate();
当通过调试器运行时,我们的SQL语句似乎是在第一行执行之后,甚至在第二行执行之前执行的。当执行第二行时,将再次执行drop SQL,并导致错误,因为用户名tmp不再存在

这只会发生在SQL Server上,而不会发生在Oracle和Postgres上,它们具有类似的drop SQL查询


这是一个已知的问题吗?除了移动到语句而不是PreparedStatement之外,还有其他常见的解决方法吗?

我认为最好的办法是对测试数据库运行SQL Server Profiler,看看在运行此代码时服务器到底受到了什么影响。通过C#prepared语句,您可以看到

declare @p1 int
set @p1=-1
exec sp_prepexec @p1 output, N'@param, varchar(100)', ...
select @p1
Java或SQL客户端库可能使用不同的技术

话虽如此,prepared语句的设计只是为了缓存和参数化可参数化的重复的类似语句。这样做的目的是避免重新编译SQL语句。如果您没有发出许多重复的、类似的语句,那么准备好的语句对您不利,缓存SQL也没有用。就我个人而言,我无法想象使用“drop login”会有多大帮助


除此之外,我认为DROP LOGIN语句不能在t-SQL中使用参数。

当您创建
PreparedStatement
时,查询将被发送到服务器进行预编译()

猜测一下,SQLServer发现没有占位符,只是执行查询


从评论中判断,您已经知道解决方法是创建一个
语句

好吧,您的语句不包含任何变量,因此实际上没有任何需要“准备”的内容。您是否尝试过仅使用一个语句?我同意drop不是准备好的语句的好选择,事实上,我们切换到语句,问题就解决了。然而,这是一个库代码,我们可能需要将其用于不同的查询,所以我想找到问题的根源。我同意drop不是准备语句的好候选,事实上,我们切换到语句,问题就解决了。但是,这是一个库代码,我们可能需要将其用于不同的查询,因此我想找到问题的根源。