我试图使用JPA (和Spring 2)来执行Server存储过程。以下是程序:
CREATE Procedure [dbo].[GetStatus]
@statusId char(32),
@bar int
AS
BEGIN TRY
SELECT IIF(COUNT(1)>0 , 1, 0) FROM Status WITH (NOLOCK)
WHERE statusId = @statusId AND bar = @bar
END TRY
BEGIN CATCH
EXEC EventLog @@PROCID
END CATCH
GO我试图捕获返回值,但无法找到这样做的方法。我的实体是:
@Entity
@Table(name = "status")
@NamedStoredProcedureQueries({
@NamedStoredProcedureQuery(name = "getStatusByStatusId",
procedureName = "GetStatus",
parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "statusId", type = String.class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "bar", type = Integer.class) })
})
public class Status implements Serializable {
@Id
@GeneratedValue
private Long id;
private Integer bar;
private String statusId;
private Date createDate;
}我的存储库是:
@Repository
public interface StatusRepository extends JpaRepository<Status, Long> {
@Procedure("GetStatus")
int getStatusByStatusId(@Param("statusId") String statusId, @Param("bar") Integer bar);
}当我从服务层运行此方法时,会得到一个错误:
没有为存储过程定义参数输出.“
我尝试添加参数(通过将它命名为count并键入Integer)。我试过List,Object[],但是什么都没成功。唯一起作用的是,如果我将存储库方法更改为返回void。但在这种情况下,我无法得到返回值。那么,我的问题是,我如何才能得到这个选择值?任何帮助都是非常感谢的。我的app.yml有:
datasource:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://dev.lsd.com:1433;databaseName=Qrex;integratedSecurity=true;MultiSubnetFailover=true;authenticationScheme=JavaKerberos
username:
password:
jpa:
hibernate:
ddl-auto: none
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
show-sql: true
database-platform: org.hibernate.dialect.SQLServerDialect
database: sql_server我对等级的依赖是:
compile "com.microsoft.sqlserver:mssql-jdbc:6.4.0.jre8"发布于 2018-05-09 08:56:07
我不相信JPA能够处理存储过程,返回任意数量的结果集和/或更新计数和/或错误消息。我看到的所有例子都很简单。您的过程可以返回:
EventLog过程返回什么。可能是任何东西下面是如何直接使用JDBC (没有OUT参数,所以普通的PreparedStatement就可以这么做)。
下面是如何使用JDBC只获取一个结果集:
try (PreparedStatement stmt = connection.prepareStatement(
"EXEC [GetStatus] ?, ?"
)) {
stmt.setString(1, statusId);
stmt.setInt(2, bar);
if (stmt.execute()) {
try (ResultSet rs = stmt.getResultSet()) {
// Do your thing
}
}
}下面是如何获取任意数量的结果集
如果您也想检索EventLog生成的任何内容,您可能更愿意调用它:
try (PreparedStatement stmt = connection.prepareStatement(
"EXEC [GetStatus] ?, ?"
)) {
stmt.setString(1, statusId);
stmt.setInt(2, bar);
fetchLoop:
for (int i = 0, updateCount = 0; i < 256; i++) {
boolean result = (i == 0)
? s.execute()
: s.getMoreResults();
if (result)
try (ResultSet rs = s.getResultSet()) {
System.out.println("Result :");
while (rs.next())
System.out.println(" " + rs.getString(1));
}
else if ((updateCount = s.getUpdateCount()) != -1)
System.out.println("Update Count: " + updateCount);
else
break fetchLoop;
}
}我在这里更详细地描述了这种获取任意结果集和更新计数的方法。,特别是如何正确地获取异常和警告。
如果使用该方法,则可能需要将该逻辑封装在某些库代码中。
使用jOOQ
还有可能在这些方面使用jOOQ (免责声明:我为供应商工作),在这种情况下,您可以调用:
Results results = ctx.fetchMany("EXEC [GetStatus] ?, ?", statusId, bar);若要获得org.jooq.Results类型,它包装交错的结果集、更新计数、异常和警告
https://stackoverflow.com/questions/50246308
复制相似问题