使用临时表的有效SQL不返回结果集

时间:2012-11-07 21:47:48

标签: java tsql jdbc sqljdbc

过去几个小时我一直在搜索谷歌和堆栈溢出,似乎无法在这个问题上找到完全匹配。我对java比较新,所以如果我只是做一些非常愚蠢的事情,请纠正我!

问题:执行try-with-resource查询(statement.executeQuery(stmt))时,我收到'Statement没有返回结果集'

我可以保证这是有效的SQL,并且当通过SSMS运行时查询可以工作 - 并且当使用select ... into ... from style语法时,此查询也可以[在java中]工作。 select ... into ... from不是一个可行的选项,因为它会产生性能问题(由于资源利用,23秒查询变为5分钟以上的查询)

概念证明: SQL文件:c:\ test.sql

set nocount on
create table #test (loannum int)
insert into #test (loannum)
select 1
select * from #test
drop table #test

此查询用于创建缓存的结果集,以便我可以围绕其他函数传递数据,而无需保持与数据库的开放连接...

注意:下面的SQLInfo只是“C:\ test.sql” <剪断>

try(BufferedReader in = new BufferedReader(new FileReader(SQLInfo)))
                {
                    String str;
                    StringBuffer sb = new StringBuffer();
                    while((str = in.readLine()) != null)
                    {
                        sb.append(str + System.getProperty("line.separator"));
                    }

                    _stmt = sb.toString();
                }

< /剪断>

以后用于下面...... <剪断>

try (Connection connection = DriverManager.getConnection(CONNECTION);
                Statement statement = connection.createStatement();
                ResultSet resultset = statement.executeQuery(_stmt)
            ) 
        {

            crs.populate(resultset);

            return crs;
        }
        catch (SQLException e) 
        {
            e.printStackTrace();
        }
        return crs;

< /剪断>

我期待的是一个缓存的结果集,它将在defaulttablemodel中用于显示“loannum”字段,值为1 - 我真正得到的是以下错误:“com.microsoft.sqlserver .jdbc.SQLServerException:该语句未返回结果集...“

如果我将SQL修改为以下内容:

set nocount on
select 1 as loannum
into #test
select * from #test
drop table #test

我得到“loannum”的预期回报结果,值为1.

它似乎与executeQuery方法中的create table语句有关,但它是一个临时表!有没有办法让上面的工作与create table(值类型,值类型,值类型)插入到...方法?

**注意:我试图使用.execute(String)方法,并解析返回结果。它似乎有同样的问题,但我完全有可能错误地实现它。

**次要说明:defaulttablemodel工作正常,并将信息返回到屏幕上显示的JTable。这会动态分配列名称,并显示关联的值。如果需要,我可以提供此代码的示例,但我不认为它与问题相关,因为这只是在创建结果集时失败,而不是在它尝试将信息分配给表模型时。

[在此处编辑]:在这种情况下,SQL端的存储过程不是可行的选项。这是一个针对数据仓库的查询,该数据仓库不允许将存储过程作为公司策略(我已经推迟了,并且已被击落) - 结果,我正在研究这个... hackish解决方案。

希望有人对此问题有所了解!

1 个答案:

答案 0 :(得分:0)

事实证明,在我更新使用execute命令之后,我不小心将它包含在try-with-resources块中,导致将一个封闭的数据集返回给调用函数,然后该函数将返回一个空的结果集传递给创建默认的表模型。糟糕。

最终,执行查询使用以下内容(仍然需要重构和清理,这只是'让它工作'):

try 
        {
            boolean hasResults = statement.execute(_stmt);

            do { //I think... this could only possibly get one result. FIXME

            if (hasResults) 
            {
                try(ResultSet rs = statement.getResultSet())
                {
                    CachedRowSetImpl crs = new CachedRowSetImpl();
                    crs.populate(rs);

                    return crs;
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }

            hasResults = statement.getMoreResults();

            } while (hasResults || statement.getUpdateCount() != -1);

            } 
        catch (Exception e) 
        {
            e.printStackTrace();
        } 
        finally 
        {
            statement.close();
        }