我在T-SQL中有以下SQL查询:
SELECT a.ReportDate,
a.Value,
a.Quantity,
a.ID,
a.Code
FROM AQF.fCalc(@data) a
@data
是varbinary
。我正在尝试使用JPA复制此查询。 (我实际上使用的是Spring Data JPA 1.10.2。)我在MyRepository
中定义了以下内容:
@Query("SELECT a "
+ "FROM function('AQF.fCalc', :data) a "
)
List<MyClass> getCalcData(@Param("data") byte[] data);
MyClass
如下:
@Entity
@Data // using lombok to create setters, getters, etc.
public class MyClass {
@Id
private Long id;
private Date reportDate;
private BigDecimal value;
private BigDecimal quantity;
private String code;
}
当我调用getCalcData时,收到以下错误:
antlr.NoViableAltException: unexpected token: function
at org.hibernate.hql.internal.antlr.HqlBaseParser.fromRange(HqlBaseParser.java:1501) [hibernate-core-5.0.9.Final.jar:5.0.9.Final]...
如何使用JPA调用函数AQF.fCalc(并传入字节数组)?
更新1
我现在也尝试使用原生查询,但现在我收到一条错误说明:
java.sql.SQLException: An error occurred while getting new row from user defined Table Valued Function :
System.Xml.XmlException: Unexpected end of file has occurred. The following elements are not closed: Data, Report. Line 24, position 804.
以下是MyRepository
中原生查询的测试代码:
@Query(value = "SELECT a.code "
+ "FROM AQF.fCalc(?1) a",
nativeQuery = true)
List<String> getCalcData(byte[] data);
更新2
我能够解决上面“更新1”中提到的错误。 getCalcData
中的数据字节数组已损坏。一旦我解决了这个问题,错误就不再出现了。所以,现在我可以作为本机查询运行。但是,我仍然想知道如何使用JPQL来调用此函数。
答案 0 :(得分:-1)
您可以使用 StoredProcedureQuery 。来自javadoc
用于控制存储过程查询执行的接口。
请参阅此示例代码。
在此示例中假设您的SQL函数名称为sales_tax。
EntityManager em = factory.createEntityManager();
// Create call stored procedure
em.getTransaction().begin();
StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("sales_tax");
// set parameters
storedProcedure.registerStoredProcedureParameter("subtotal", Double.class, ParameterMode.IN);
storedProcedure.registerStoredProcedureParameter("tax", Double.class, ParameterMode.OUT);
storedProcedure.setParameter("subtotal", 1f);
// execute SP
storedProcedure.execute();
// get result
Double tax = (Double)storedProcedure.getOutputParameterValue("tax");
System.out.println("Tax is: " + tax);
em.getTransaction().commit();
em.close();