2011-04-16 63 views
1

我嘗試使用Hibernate的查詢類來調用存儲過程:是否可以使用Hibernate Query調用SQL Server 2008存儲過程?

Query q = ssn.createSQLQuery("{ ? = call SEARCH_RESULT(?,?,?) }"); 

int idx = 0; 
q.setParameter(idx, sc.getId(), StandardBasicTypes.INTEGER); 
q.setString(++idx, sc.getNum() == null ? null : sc.getNum() 
     .toString()); // second parameter 
q.setString(++idx, sc.getName()); 
List list = q.list(); 

但它給下面的異常,雖然沒有第四個參數: 請求有益的建議和潛在的解決方案。

com.microsoft.sqlserver.jdbc.SQLServerException: The value is not set for the parameter number 4. 
    com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:171) 
    com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.buildParamTypeDefinitions(SQLServerPreparedStatement.java:262) 
    com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.buildPreparedStrings(SQLServerPreparedStatement.java:221) 
    com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doPrepExec(SQLServerPreparedStatement.java:598) 
    com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:386) 
    com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:340) 
    com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4575) 
    com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1400) 
    com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:179) 
    com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:154) 
    com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:283) 
    org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208) 
    org.hibernate.loader.Loader.getResultSet(Loader.java:1953) 
    org.hibernate.loader.Loader.doQuery(Loader.java:802) 
    org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) 
    org.hibernate.loader.Loader.doList(Loader.java:2533) 
    org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276) 
    org.hibernate.loader.Loader.list(Loader.java:2271) 
    org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:316) 
    org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1842) 
    org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165) 
    org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:157) 

回答

1

我認爲有4個參數

Query q = ssn.createSQLQuery("{ ? = call SEARCH_RESULT(?,?,?) }"); 

有4個問號,一個似乎是一個輸出參數,以及3個輸入參數。還是1個回報和3個投入?

不知道NHibernate的,從未使用過它執行存儲的特效,但它看起來像你告訴NHibernate的期望4個PARMS,只給它3

+0

這似乎是標準調用存儲過程的方式。根據Hibernate文檔,推薦的調用形式是標準的SQL92:{? =調用函數名()}或{? = call procedureName()。本機調用語法不被支持,事實是我的存儲過程返回的數據行並不完全映射到任何實體,如果需要設置它,我該如何設置這個參數? – Champ 2011-04-17 06:13:44

0

Hibernate不知道什麼樣的對象,以將您的存儲過程結果轉換爲。我通常爲我所有的SP指定一個返回代碼/值,然後確保在我的SP返回結果中將結果類別字段與相同的列別名映射。

例如...

{ call my_function(:param1, :param2) } 

return_code = 404, message = "Page not found" 

return_code = 200, message = "OK" 

類映射像任何其他POJO,只是一定要使它可序列化。我用的是這樣的:

@NamedNativeQueries({ 
    @NamedNativeQuery(name = "myFunction", 
        query = "{ call my_function(:param1, :param2) }", 
        resultClass = StoredProc.class) 
}) 
@Entity 
public class StoredProc implements Serializable { 

    private Integer returnCode; 
    private String message; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "return_code", nullable = false, unique = true) 
    public Integer getReturnCode() { 
    return returnCode; 
    } 
    public void setReturnCode(Integer returnCode) { 
    this.returnCode = returnCode; 
    } 

    @Column(name = "message") 
    public String getMessage() { 
    return message; 
    } 
    public void setMessage(String message) { 
    this.message = message; 
    } 

} 

注意的方式有細微的差別我打電話給我的存儲特效 - 我不使用分配式「{=調用創建my_function(?,?)}?」,而是使用直的「{call my_function(:param1,:param2)}」。在我的代碼中,我使用@NamedNativeQuery註釋定義了這些SP,並將它們全部包裝在@NamedNativeQueries註釋(複數!)中,並將其粘貼在我的StoredProc類上。這樣一切都在正確的地方......很好,很整齊。

當我想調用其中的一個,從代碼,它的死簡單:

(StoredProc) getSession().getNamedQuery("myFunction") 
         .setParameter("param1", value) 
         .setParameter("param2", value2) 
         .uniqueResult(); 

尼斯和簡單。如果SP引發任何錯誤,我將它們放在返回消息中,然後我可以處理,但我喜歡(自動發送錯誤報告,向UI發送消息等)

相關問題