我有一个SQL语句,它在MS Server Management Studio中执行时有效,并且在从C#提交时起作用,但在从Java(1.6,使用sqljdbc4.jar)提交时不起作用.基本问题似乎是选择一个表变量.继第一条评论之后,我使用更简单的例子完全重...
我有一个SQL语句,它在MS Server Management Studio中执行时有效,并且在从C#提交时起作用,但在从Java(1.6,使用sqljdbc4.jar)提交时不起作用.
基本问题似乎是选择一个表变量.继第一条评论之后,我使用更简单的例子完全重写了这个问题,以显示哪些有效,哪些无效.
以下查询:
DECLARE @IsLoadRaw as INT = ?
DECLARE @PrimaryID as varchar(1000) = ?
--Declare temporary table to hold message IDs and fill according to Primary ID.
DECLARE @MessageIDs TABLE ( MessageID BIGINT )
SELECT MessageID FROM Messages WHERE PrimaryID = @PrimaryID
在SQL Management Studio和从Java提交时都可以使用.在这两种情况下,它都返回一个带有两个MessageID的结果集(对于我用于测试的给定PrimaryID是正确的).
以下查询:
DECLARE @IsLoadRaw as INT = ?
DECLARE @PrimaryID as varchar(1000) = ?
--Declare temporary table to hold message IDs and fill according to Primary ID.
DECLARE @MessageIDs TABLE ( MessageID BIGINT );
INSERT @MessageIDs SELECT MessageID FROM Messages WHERE PrimaryID = @PrimaryID;
SELECT * FROM @MessageIDs;
在SQL Management Studio中工作,它返回具有相同两个MessageID的结果集.从Java提交时,它不会返回任何结果集.
使用@MessageIDs的完整语句在通过ADO.NET从C#提交时起作用.我假设这里的第二个样本也可以.该问题与Java隔离,似乎与使用表变量有关.由于代码看起来正确并在SQL Management Studio下运行,我对如何调试它感到困惑.
知道为什么这不适用于Java吗?在从Java提交时,我可以使用哪些工具来了解服务器正在使用此查询执行的操作?
解决方法:
我做了一些挖掘,找到了答案:
INSERT @MessageIDs SELECT MessageID FROM Messages WHERE PrimaryID = @PrimaryID;
从Java提交时返回更新计数.从C#或SQL Management Console提交时,它不会返回更新计数.我没想到这一点所以需要一些挖掘才能找到.
用于逐步执行execute()结果的java API令人困惑,没有可能的例子,至少有一个我发现并不完全正确.我将解释我是如何理解这一点的.
由于大多数语句都很简单,只有一个更改或一个选择,因此Statement上有方便的执行方法,例如executeQuerry(),它返回一个结果集.大多数情况下使用这些,这是故事的结尾.
如果你有一个更复杂的语句,它会执行几个你调用execute()并返回一个事物列表的东西. INSERT,UPDATE和DELETE(我相信)返回修改的记录数. SELECT返回结果集.执行复杂语句的结果是更新计数和结果集的列表,按执行顺序排列.然后编写逐步执行此列表的代码,处理每个项目.
该声明
DECLARE @MessageIDs TABLE ( MessageID BIGINT )
INSERT @MessageIDs SELECT MessageID FROM Messages WHERE PrimaryID = @PrimaryID;
SELECT * FROM Messages WHERE MessageID IN (SELECT MessageID FROM @MessageIDs) ORDER BY MessageID;
SELECT * FROM Attrs WHERE MessageID IN (SELECT MessageID FROM @MessageIDs) ORDER BY MessageID;
返回2个结果集.在java中,由于我不知道的原因,仅在java中,INSERT @MessageIDs …语句返回更新计数,这是列表中的第一项.
用于此的java API令人困惑. Statement.execute()和Statement.getMoreResults()返回:
>如果下一个结果是ResultSet,则为true
>如果下一个结果是更新计数或者没有更多结果,则为false
false有两个含义,不能解释为结果的结束.您还必须检查非零更新计数.
最终的功能代码最终看起来像这样:
List<DtaMessage> msgList = new ArrayList<DtaMessage>();
boolean isResult = stmt.execute();
// Skip over update counts.
while (!isResult) {
if (stmt.getUpdateCount() == 0)
// End of results.
return msgList;
isResult = stmt.getMoreResults();
}
// Process first result set.
ResultSet rs = stmt.getResultSet();
while (rs.next())
{
DtaMessage msg = PopulateMessage(rs, isLoadRaw);
msgList.add(msg);
}
rs.close();
// Skip over update counts.
isResult = stmt.getMoreResults();
while (!isResult) {
if (stmt.getUpdateCount() == 0)
// end of results.
return msgList;
isResult = stmt.getMoreResults();
}
// Process second result set.
rs = stmt.getResultSet();
while (rs.next())
{
// process.
}
rs.close();
return msgList;
虽然我的示例SQL没有做任何可以在两个结果集之间生成更新计数的方法,但是这个方法将处理来自几个不同SQL语句的结果,所以我添加了代码来跳过在某些情况下可能出现的日期计数.
本文标题为:从Java调用SQL Server中的表变量的问题
基础教程推荐
- 解析MyBatis源码实现自定义持久层框架 2022-11-20
- Java三目运算符的实战案例 2023-05-08
- 关于Spring中@Transactional事务回滚的注意事项 2023-07-14
- SpringBoot 实现自定义的 @ConditionalOnXXX 注解示例详解 2023-05-08
- 利用Java实现天气预报播报功能 2023-01-24
- 一文搞懂Java SPI机制的原理与使用 2023-06-06
- Mybatis超详细讲解构建SQL方法 2023-02-19
- SpringBoot bean依赖属性配置详细介绍 2023-06-01
- Java深入讲解SPI的使用 2023-01-09
- ubuntu 14.04 java开发环境搭建 jdk 以及 inteliJ IDEA安装 2023-08-31