JDBC - 存储过程的varbinary(max)out参数被截断为8000字节

时间:2016-10-06 18:50:36

标签: sql-server jpa jdbc spring-data-jpa jtds

我正在使用带有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

1 个答案:

答案 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());