【问题标题】:JPA - Can a stored procedure be called without providing optional parameters?JPA - 可以在不提供可选参数的情况下调用存储过程吗?
【发布时间】:2017-02-16 21:00:53
【问题描述】:

我正在调用带有许多可选参数的第三方存储过程。它位于 MS SQL Server 2008 R2 中,如下所示:

procedure [dbo].[pTest]
    @ReportDate varbinary(max) out, 
    @Optional1 varchar(max) = null,
    @Optional2 varbinary(max) = null,
    @Date varchar(max) = null,
    -- ~20 more optional params of various types 
as
begin
select * from test
end

我使用 Spring Data JPA 1.10.2 和 com.microsoft.sqlserver 的 sqljdbc 4.2 从 java 调用它。

我只想用两个参数 ReportDate 和 Date 调用该过程。其余参数可以保持默认值(即 null)。我的代码如下:

@Entity
@NamedStoredProcedureQuery(name = "Test.get", procedureName = "pTest", parameters = {
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "ReportData", type = byte[].class),          
@StoredProcedureParameter(mode = ParameterMode.IN, name = "Date", type = String.class)

          })
public class Test {

    // serves no purpose other than to meet
    // JPA requirement
    @Id
    private byte[] reportData;
}

Spring 数据存储库:

public interface TestRepository  extends Repository<Test, Long> {
    @Procedure("pTest")
    byte[] get(@Param("Date") String date);
}

测试代码:

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional(transactionManager="transactionManager")
public class TestRepositoryTest {

    @Autowired
    private TestRepository testRepository;

    @Test
    public void testGet() throws SQLException {

        byte[] blob = testRepository.get("hi");
        //error occurs
    }

}

我收到以下错误:

   o.h.engine.jdbc.spi.SqlExceptionHelper   : Error preparing CallableStatement [pTest]

com.microsoft.sqlserver.jdbc.SQLServerException: The index 4 is out of range.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:191) ~[sqljdbc-4.2.jar:na]

我得到这个是因为我没有指定 Optional1 和 Optional2。现在,如果我将 Optional1 和 Optional2 添加为 @StoredProcedureParameters 并作为参数添加到 TestRepository 的 getTest 方法,我将不再收到错误消息。但是,我必须传入一个非空值,否则我会收到另一个错误,抱怨我没有传递任何值。

如何在不指定 Optional1 和 Optional2 的情况下调用此存储过程?

在某些情况下,我需要调用一个存储过程,我只需要设置第 15 个参数。我真的不想在我的代码中定义其他 14 个参数。即使我这样做了,我也不能将它们设置为空。

【问题讨论】:

    标签: java hibernate jpa stored-procedures spring-data-jpa


    【解决方案1】:

    使用 Microsoft 的 JDBC 驱动程序是不可能的。两种选择:

    1. 使用 jTDS(如果存储过程返回 >8000 字节,则不能选择)
    2. 创建一个仅包含所需参数的包装存储过程,并让它调用其他存储过程。如果您没有在数据库上创建存储过程的权限,这可能不是一个选项。

    就我而言,选项 2 有效,因为我确实有权创建存储过程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      • 1970-01-01
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多