查询返回多个结果集
我有一个MSSQL
数据库,并运行以下查询:
select * from projects; select * from user
上面的查询一次返回两个结果集,我无法单独触发两个查询。 如何在Java类中同时处理结果集?
正确的代码来处理JDBC语句返回的多个ResultSet
:
PreparedStatement stmt = ...; boolean isResultSet = stmt.execute(); int count = 0; while(true) { if(isResultSet) { rs = stmt.getResultSet(); while(rs.next()) { processEachRow(rs); } rs.close(); } else { if(stmt.getUpdateCount() == -1) { break; } log.info("Result {} is just a count: {}", count, stmt.getUpdateCount()); } count ++; isResultSet = stmt.getMoreResults(); }
重要部分:
-
getMoreResults()
和execute()
返回false
以指示语句的结果只是一个数字而不是ResultSet
。 - 您需要检查
stmt.getUpdateCount() == -1
以了解是否有更多结果。 - 确保关闭结果集或使用
stmt.getMoreResults(Statement.CLOSE_CURRENT_RESULT)
您可以使用Statement.execute(),getResultSet();
PreparedStatement stmt = ... prepare your statement result boolean hasResults = stmt.execute(); while (hasResults) { ResultSet rs = stmt.getResultSet(); ... your code parsing the results ... hasResults = stmt.getMoreResults(); }
是的你可以。 请参阅此MSDN文章https://msdn.microsoft.com/en-us/library/ms378758(v=sql.110).aspx
public static void executeStatement(Connection con) { try { String SQL = "SELECT TOP 10 * FROM Person.Contact; " + "SELECT TOP 20 * FROM Person.Contact"; Statement stmt = con.createStatement(); boolean results = stmt.execute(SQL); int rsCount = 0; //Loop through the available result sets. do { if(results) { ResultSet rs = stmt.getResultSet(); rsCount++; //Show data from the result set. System.out.println("RESULT SET #" + rsCount); while (rs.next()) { System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName")); } rs.close(); } System.out.println(); results = stmt.getMoreResults(); } while(results); stmt.close(); } catch (Exception e) { e.printStackTrace(); } }
我测试了它,它工作正常。
public static void executeProcedure(Connection con) { try { CallableStatement stmt = con.prepareCall(...); ..... //Set call parameters, if you have IN,OUT, or IN/OUT parameters boolean results = stmt.execute(); int rsCount = 0; //Loop through the available result sets. while (results) { ResultSet rs = stmt.getResultSet(); //Retrieve data from the result set. while (rs.next()) { ....// using rs.getxxx() method to retieve data } rs.close(); //Check for next result set results = stmt.getMoreResults(); } stmt.close(); } catch (Exception e) { e.printStackTrace(); } }
在使用java之前,您需要查看RESULT SETS子句。
MSSQL具有此function,可以更实用的方式帮助您使用Java代码。
此示例将执行两个查询:
EXEC('SELECT id_person, name, age FROM dbo.PERSON; SELECT id_url, url FROM dbo.URL;') WITH RESULT SETS ( ( id_person BIGINT, name VARCHAR(255), age TINYINT ), ( id_url BIGINT, url VARCHAR(2000) ) );
您也可以将存储过程与RESULT SETS一起使用。
更多关于: https : //technet.microsoft.com/en-us/library/ms188332(v = sql.110).aspx
Akash和Juergen提出的UNION方法是可行的,但需要稍微多一点的工作:
- 确定两个表共享哪些列。
- 确定哪些列特定于其中一个表。
- 编写一个查询,将两个表中的所有列联合起来,公共列出现在两个select子句中的相同位置,空值替换特定于表的列。 您可能还需要一个列来指示哪些行来自哪些表。
因此,例如,考虑具有以下结构的表:
Projects -------- ID Name Budget Users ----- ID Name PhoneNo
要列出两个表的结果,您可以使用如下查询:
select 'Projects' table_name, ID, Name, null as PhoneNo, Budget from Projects union all select 'Users' table_name, ID, Name, PhoneNo, null as Budget from Users
根据您的RDBMS,您可能需要将空值显式转换为所需的数据类型。
UNION ALL查询允许您组合2个或更多“选择”查询的结果集。 它返回所有行(即使该行存在于多个“select”语句中)。
UNION ALL查询中的每个SQL语句必须在具有相似数据类型的结果集中具有相同数量的字段………
select * from projects UNION ALL select * from user
答案:这是不可能的。 唯一的方法:将它们作为单独的查询运行。