私の質問は
sql = "SELECT SUM(TOTAL_BYTES_DELIVERED) / SUM(TOTAL_TIME_TAKEN_IN_DELIVERY)
FROM MV_MFT_TRANSFER
WHERE TRANSFER_INITIATION_TIME > :startDate
AND TRANSFER_INITIATION_TIME < :endDate"
Query query = em.createNativeQuery(sql);
query.setParameter("startDate", startDate, TemporalType.DATE);
query.setParameter("endDate", endDate, TemporalType.DATE);
query.getResultList();'
これを実行すると、エラーが発生します
SQLExceptionTHrown:
<Sep 11, 2012 12:50:46 PM PDT> <Warning> <EclipseLink> <BEA-2005000> <2012-09-11 12:50:46.893--UnitOfWork(1387841584)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20120804-d768c4f): org.Eclipse.persistence.exceptions.DatabaseException
Internal Exception: Java.sql.SQLException: Missing IN or OUT parameter at index:: 1
Error Code: 17041
Call: SELECT SUM(TOTAL_BYTES_DELIVERED) / SUM(TOTAL_TIME_TAKEN_IN_DELIVERY) FROM MV_MFT_TRANSFER WHERE TRANSFER_INITIATION_TIME > :startDate AND TRANSFER_INITIATION_TIME < :endDate
Query: DataReadQuery(sql="SELECT SUM(TOTAL_BYTES_DELIVERED) / SUM(TOTAL_TIME_TAKEN_IN_DELIVERY) FROM MV_MFT_TRANSFER WHERE TRANSFER_INITIATION_TIME > :startDate AND TRANSFER_INITIATION_TIME < :endDate")>
***SQLException in init() TRANSFER METRICS BEAN****
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20120804-d768c4f): org.Eclipse.persistence.exceptions.DatabaseException
Internal Exception: Java.sql.SQLException: Missing IN or OUT parameter at index:: 1
次の解決策が機能するはずです。
sql = "SELECT SUM(TOTAL_BYTES_DELIVERED) / SUM(TOTAL_TIME_TAKEN_IN_DELIVERY)
FROM MV_MFT_TRANSFER
WHERE TRANSFER_INITIATION_TIME > ?
AND TRANSFER_INITIATION_TIME < ?"
Query query = em.createNativeQuery(sql);
query.setParameter(1, startDate, TemporalType.DATE);
query.setParameter(2, endDate, TemporalType.DATE);
query.getResultList();
位置パラメータを使用すれば機能するようです。名前付きパラメータとネイティブクエリを組み合わせることはできません。ここにいくつかのリンクがあります:
http://Java.boot.by/scbcd5-guide/ch08s05.html
http://www.wisegeek.com/what-are-native-queries.htm
さらに、「ネイティブクエリに移植可能に使用できるのは位置パラメータバインディングのみ」をグーグルで検索してください。
編集:同様の問題を持つ質問へのより多くのリンク:
この記事は本当に役に立ちました!
http://software-security.sans.org/developer-how-to/fix-sql-injection-in-Java-persistence-api-jpa
記事の要点は次のとおりです。
これらは安全でないクエリです。使用しないでください。文字列の連結が悪い:
List results = entityManager.createQuery("Select order from Orders order where order.id = " + orderId).getResultList();
List results = entityManager.createNativeQuery("Select * from Books where author = " + author).getResultList();
int resultCode = entityManager.createNativeQuery("Delete from Cart where itemId = " + itemId).executeUpdate();
これらはsafeクエリです。
/* positional parameter in JPQL */
Query jpqlQuery = entityManager.createQuery("Select order from Orders order where order.id = ?1");
List results = jpqlQuery.setParameter(1, "123-ADB-567-QTWYTFDL").getResultList();
/* named parameter in JPQL */
Query jpqlQuery = entityManager.createQuery("Select emp from Employees emp where emp.incentive > :incentive");
List results = jpqlQuery.setParameter("incentive", new Long(10000)).getResultList();
/* named query in JPQL - Query named "myCart" being "Select c from Cart c where c.itemId = :itemId" */
Query jpqlQuery = entityManager.createNamedQuery("myCart");
List results = jpqlQuery.setParameter("itemId", "item-id-0001").getResultList();
/* Native SQL */
Query sqlQuery = entityManager.createNativeQuery("Select * from Books where author = ?", Book.class);
List results = sqlQuery.setParameter(1, "Charles Dickens").getResultList();
JPAでは
これを使用する場合:
クエリクエリ= em .createNativeQuery(sql);
設定パラメータのインデックスを設定する必要があります。クエリには複数のパラメータがあることに注意してください。