【发布时间】:2021-07-29 04:56:30
【问题描述】:
我有一个包含大量逻辑的庞大脚本,最后是 select statement,它返回最终结果。
许多人都知道 JDBC 不应该开箱即用地运行 SQL 脚本(带有多个语句),因此我将脚本包装到 begin ... end 块中,使其成为单个语句块,以便我可以一次性执行它。
一切似乎都很好......除了我无法从begin ... end 块中获取结果集(下面的代码打印“无数据”)。所以我不得不把脚本分成两部分——所有的逻辑(1)+最终的选择语句(2)。
val url = "jdbc:sqlserver://" + mssqlServer + ";integratedSecurity=true;"
val connMSSQL = java.sql.DriverManager.getConnection(url)
val qqq0 = """begin
|
|if object_id('tempdb..#ttt') is not null drop table #ttt
|
|create table #ttt(i int, v varchar(10))
|
|insert into #ttt
|select 0, 'qwerty' union all select 1, 'hello'
|
|select 1 id, 0 value
|
|end""".stripMargin
val qqq = "select * from #ttt"
val stmt = connMSSQL.createStatement()
stmt.execute(qqq0)
if (stmt.getResultSet==null) println("No data")
val rs = stmt.executeQuery(qqq)
问题是 - 是否有任何方法可以从 begin ... end 块获取结果集?如果答案是否定的,那么我们将非常感谢您的解释。
PS。如果我将所有代码包装到过程 my_proc 中,我可以轻松获得结果,但在我的特定情况下,在 DB 中创建对象不是一个选项。
这样工作
val stmt1 = connMSSQL.createStatement()
stmt1.execute("my_db..my_proc")
val rs1 = stmt1.getResultSet
这样也行
val stmt2 = connMSSQL.createStatement()
val rs2 = stmt2.executeQuery("my_db..my_proc")
在这两种情况下,当代码与匿名块而不是过程一起使用时,记录集都等于 null。
PPS。不用说,如果将begin ... end块复制并粘贴到管理工作室并用F5运行它,它会毫无问题地返回结果。
更新
对我来说,这种行为仍然很奇怪,但幸运的是它只适用于 set nocount on 和 getMoreResults。
但是...它仅适用于第一个语句。
因此,如果我将nocount 包含在原始 SQL 脚本中,那么对于下面的代码
val stmt1 = connMSSQL.createStatement()
println(stmt1.execute(qqq0))
println(stmt1.getMoreResults())
if (stmt1.getResultSet==null) println("No data") else println("Yes data")
val stmt2 = connMSSQL.createStatement()
println(stmt2.execute(qqq0))
println(stmt2.getMoreResults())
if (stmt2.getResultSet==null) println("No data") else println("Yes data")
输出如下
false
true
Yes data
false
false
No data
现在的问题是如何让它正常工作,而不仅仅是第一个语句。
更新 2
版主提供的链接均未解释 createStatement 的意外行为。
【问题讨论】:
-
尝试将
SET NOCOUNT ON;添加为脚本中的第一条语句。
标签: java sql sql-server scala jdbc