PreparedStatement在SQL Server上的prepareStatement上执行

时间:2009-08-16 14:02:00

标签: java sql-server jdbc

我们有类似以下的Java代码:

PreparedStatement stmt = connection.prepareStatement("drop login tmp");
int result = stmt.executeUpdate();

当运行调试器时,似乎我们的SQL语句在执行第一行之后执行,甚至在第二行执行之前执行。执行第二行时,再次执行drop SQL,并导致错误,因为用户名tmp不再存在。

这只针对SQL Server,但不针对具有类似丢弃SQL查询的Oracle和Postgres。

这是一个已知问题吗?是否有一个共同的解决方法,除了转移到Statement而不是PreparedStatement?

2 个答案:

答案 0 :(得分:1)

我认为您最好的选择是针对测试数据库运行SQL Server Profiler,并在运行此代码时查看服务器上的内容。使用C#预处理语句,您会看到类似

的内容
declare @p1 int
set @p1=-1
exec sp_prepexec @p1 output, N'@param, varchar(100)', ...
select @p1

Java或您的SQL客户端库可能使用不同的技术。

话虽如此,预准备语句仅用于缓存和参数化可重复参数化的类似语句。我们的想法是保存重新编译SQL语句。如果你没有发出许多重复的,类似的语句,那么准备好的语句对你没有用,并且缓存SQL是没用的。我个人无法想象使用“drop login”这么多,缓存会有所帮助。

最重要的是,我认为DROP LOGIN语句不能在T-SQL中使用参数。

答案 1 :(得分:0)

创建PreparedStatement时,会将查询发送到服务器以对其进行预编译(Source)。

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

根据评论判断,您已经知道修复方法是创建Statement