为什么我的代码会出现错误:该语句未返回结果集

18
我从Microsoft SQL Server Studio执行了以下查询,它可以正常工作并显示结果:
SELECT *
INTO   #temp_table
FROM   md_criteria_join
WHERE  user_name = 'tecgaw'

UPDATE #temp_table
SET    user_name = 'tec'
WHERE  user_name != 'tec'

SELECT *
FROM   md_criteria_join
WHERE  user_name = 'tec'
   AND view_name NOT IN (SELECT view_name
                         FROM   md_criteria_join
                         WHERE  user_name = 'tecgaw')
UNION
SELECT *
FROM   #temp_table
ORDER  BY view_name,
      user_name,
      crit_usage_seq,
      crit_join_seq 

然而,如果我在Java中执行相同的查询,会抛出一个异常,指出:

该语句没有返回结果集。

这是Java代码:

statement = conn.getConnection().createStatement();
resultSet = stmt.executeQuery(sql.toString());

这是因为我无法在一个语句中执行多个 SQL 查询(即创建#temp_table、更新它,然后在我的选择语句中使用它)吗?


如果你指出 md_criteria_join 表中哪些列组成了主键,你可以将这个操作重写为单个查询。如果需要的话,我可以帮助你完成这个操作。 - Dawood ibn Kareem
pk 是我用来进行排序的最后四列。 - user2966439
4个回答

46

JDBC在处理行数时出现了混淆。

您需要使用SET NOCOUNT ON


在MS SQL的情况下,这是你应该尝试的第一个解决方案。@John 谢谢。 - Khandakar Rashed Hassan

29

使用execute语句进行数据操作,例如插入、更新和删除,而使用executeQuery进行数据检索,例如查询

我建议将程序分成两个语句,一个execute一个executeQuery

如果您不想这样做,请尝试用分号分隔语句。 但我不确定此操作是否会给您返回结果集。


好的,如果我创建单独的语句。那么临时表什么时候会消失?在我关闭结果集、语句还是连接之后? - user2966439
临时表将在第一个执行语句执行后不久消失,在这种情况下,请使用存储过程和CallableStatement - Ravindra Gullapalli
@RavindraGullapalli 你真棒。谢谢。 - Victor Viola

1
我在StackOverflow上找到了类似的问题这里。您应启用连接以支持多个语句,并使用;将它们分开。有关具体示例,请参见该答案。但是,它仅适用于MySql。
此外,我认为您可以将SQL重写为单个查询。
SELECT columnA, columnB, 'tec' as user_name from md_criteria_join
WHERE (
       user_name = 'tec' 
   AND view_name NOT IN (
       SELECT view_name 
       FROM md_criteria_join 
       WHERE user_name = 'tecgaw')
   )
   OR user_name = 'tecgaw' 
ORDER BY view_name, user_name, crit_usage_seq, crit_join_seq

另一个选择是将您的语句移至存储过程中,并使用CallableStatement从JDBC调用它。
或者,您可以尝试像这样使用多个jdbc语句来执行它。
Connection conn = conn.getConnection(); //just to make sure its on single connection
conn.createStatement("SELECT INTO #temp_table").executeUpdate();
conn.createStatement("UPDATE #temp_table").executeUpdate();
conn.createStatement("SELECT ...").executeQuery();

请注意,您需要关闭资源,并且为了更好的性能,您可以使用addBatch和executeBatch方法。

你链接的答案是针对MySQL的。JDBC语句应该一次执行一个语句,而不是多个语句。 - Mark Rotteveel
不,你的查询与我的不同。 - user2966439
实际上,这忽略了你正在将 user_name 从 tecgaw 更改为 tec 的重点。其中一种替代方法是使用存储过程并通过 JDBC 调用它。 - Antanas
我已经更新了查询。如果你的列不是太多,你可以将它们列出来并硬编码用户名称的值。 - Antanas

1
在 MS SQL 中,您还需要在存储过程的开头执行 "set nocount on" 命令,并在终止 select/update/insert 代码块语句时使用 ";"。

天啊,非常感谢!我遇到了类似的问题,而“SET NOCOUNT ON”语句解决了它。 - Vlad Eugen Nitu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接