我们有类似以下的Java代码:
PreparedStatement stmt = connection.prepareStatement("drop login tmp");
int result = stmt.executeUpdate();
当运行调试器时,似乎我们的SQL语句在执行第一行之后执行,甚至在第二行执行之前执行。执行第二行时,再次执行drop SQL,并导致错误,因为用户名tmp不再存在。
这只针对SQL Server,但不针对具有类似丢弃SQL查询的Oracle和Postgres。
这是一个已知问题吗?是否有一个共同的解决方法,除了转移到Statement而不是PreparedStatement?
答案 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
。