我正在使用带有jTds 1.3.1的Spring Data JPA 1.10.2来调用存储过程。
存储过程有一个out参数,类型为varbinary(max)的@data
。 @data
包含大约10,000个字节。
这是存储过程签名:
ALTER procedure [User].[pTest]
@data varbinary(max) out
,@name nvarchar(max) = null
,@date datetime
as
begin
.
.
.
我的实体类是:
@Entity
@NamedStoredProcedureQuery(name = "User.getUser", procedureName = "User.pTest", parameters = {
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "data", type = byte[].class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "name", type = String.class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "date", type = Date.class)
})
@Data //lombok
public class User {
// serves no purpose other than to meet
// JPA requirement
@Id
private Long id;
}
存储库代码是
public interface UserRepository extends Repository<User, Long> {
@Procedure("User.pTest")
byte[] getUserSession(@Param("name") String name,
@Param("date") Date date
);
}
我的测试代码如下,当我运行它时,我收到错误:
@Test
public void testGettingApxSession() {
Calendar cal = new GregorianCalendar(2016,6,5);
byte[] b = userRepository.getUserSession("myName", cal.getTime());
}
当我使用
注销@data
时
StringBuilder sb = new StringBuilder();
for (byte a : b) {
sb.append(String.format("%02X ", a));
}
我注意到只返回了8,000个字节。当我在SQL Server Management Studio中运行相同的存储过程时,我注意到它有大约10,000个字节,并以十六进制代码FFFF结束。
因此,从我的Java应用程序运行存储过程时,我的结果似乎被截断了。
如何防止此截断?我应该为varbinary(max)而不是byte []?
指定不同的数据类型更新
我也尝试过Microsoft的JDBC驱动程序(v 6.0.7728.100)并遇到同样的问题。我的猜测是,JDBC驱动程序(我认为)基于最大数量n
,最大值为8000,您可以在varbinary(n)
中指定。但是,varbinary
的最大容量远大于8000,并由varbinary(max)
指定。 varbinary(max)
可以容纳2 ^ 31 - 1个字节。请参阅我的问题和其他答案here
答案 0 :(得分:0)
使用Microsoft的JDBC驱动程序并将输出参数类型指定为Blob
:
@Entity
@NamedStoredProcedureQuery(name = "User.getUser", procedureName = "User.pTest", parameters = {
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "data", type = Blob.class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "name", type = String.class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "date", type = Date.class)
})
注意:这不适用于jTDS。它仍将截断任何&gt; 8000字节。
如果需要将Blob
传递回SQL Server,则必须按如下方式转换回字节数组:
byte[] bytes = blob.getBytes(1, (int) blob.length());