Oracle EBS OAF VO(View Object)開發中的綁定方式(Binding Style)的介紹
魏紅生
在OAF VO開發中,Binding Style主要用於對VO的where clause做動態傳值,總共有三種方式
1. Oracle Named
2. Oracle Positional
3. JDBC Positional
Oracle Positional
Oracle Positional 是最常用的一種方式,Oracle文檔的介紹是
This style represents parameters as colons followed by numbers, as in the following code fragment:WHERE bar = :1 AND foo = :2 In this style, the numbers are just for easier readability: Parameters are passed into the view object in the order in which the numbers occur. The above fragment, for example, is equivalent to WHERE bar = :70 AND foo = :3
簡單來說,這種方式中的參數都是以‘:’和數字來聲明的,比如:WHERE bar = :1 AND foo = :2。這種方式來說,數字只是用來增加可讀性,參數只會根據數字在VO Sql Statement中出現的順序傳入到View Object中,而不會根據數位大小而傳入。比如,上面的程式碼片段和下面這個是一樣的效果WHERE bar = :70 AND foo = :3,下面會在實現中具體介紹。
如何在VO使用Oracle Positional綁定方式
首先,我們需要在VO定義介面上進行設定,
1. Binding Style 設成 Oracle Positional
2. 在VO SQL Statement 中的where clause裡面使用 ‘:’加上數字作為參數,比如 :1.
在VO上設定完之後,我們需要執行VO查詢之前,使用vo.setWhereClauseParam(int index, Object value)對VO的綁定參數進行賦值,如下面的代碼。
public void initShipToLocation(String org_id) { RcvShipToLocationVOImpl vo =this.getRcvShipToLocationVO1(); vo.setWhereClause(null); vo.setWhereClauseParam(0, new Number(Integer.parseInt(org_id))); } |
使用Oracle Positional 綁定方式需要注意的問題
1. 在使用vo.setWhereClauseParam(int index, Object value)進行賦值的時候, index一定是從0開始的,接著就是1,2,3,…… .但是在VO SQL Statement中,參數卻不是必須從0開始,而且後面的參數的數值也不必比前面的大。比如下面的也是可以的,
但是在使用vo.setWhereClauseParam()給VO綁定參數值的時候一定要使用0和1作為index,而且index必須和綁定參數在VO SQL Statement中出現的順序對應的類型一致,比如
public void initShipToLocation(String org_id) { RcvShipToLocationVOImpl vo =this.getRcvShipToLocationVO1(); vo.setWhereClause(null); vo.setWhereClauseParam(0, new Number(Integer.parseInt(org_id))); vo.setWhereClauseParam(1, "hello"); } |
如果使用了其它的任何的Index,就會拋出下面的異常(無效的列索引)
oracle.apps.fnd.framework.OAException: oracle.jbo.SQLStmtException: JBO-27122:Invalid column index …..
2. 如果在VO SQL Statement中使用了:加數字作為綁定參數,並且在給VO設定綁定值的時候使用了vo.setWhereClauseParam(),那麼一定要保證VO的綁定方式(Binding Style)為 Oracle Positional,否則可能會出現下面的異常(無效的列類型)
oracle.apps.fnd.framework.OAException: oracle.jbo.SQLStmtException: JBO-27122:Invalid column type …..
3. 如果VO SQL Statement中兩個或多個綁定參數每次一定是一樣的值傳入,在VO SQL Statement雖然可以使用相同的數字作為綁定參數,但在使用vo.setWhereClauseParam()設定綁定值的時候也要分別設值,而且建議不要使用相同的數字作為綁定參數。
public void initShipToLocation(String org_id) { RcvShipToLocationVOImpl vo =this.getRcvShipToLocationVO1(); vo.setWhereClause(null); vo.setWhereClauseParam(1, "hello"); vo.setWhereClauseParam(2, "hello"); vo.setWhereClauseParam(0, new Number(Integer.parseInt(org_id))); } |
否則VO在執行查詢的時候會報下面的錯誤
java.sql.SQLException: 索引中丟失 IN 或 OUT參數:: 8
Oracle Named
Oracle Named 綁定方式是VO定義中的預設,也是非常常用的一種方式,Oracle文檔的介紹是
This style represents parameters as colons followed by identifiers, as in the following code fragment:WHERE bar = :barparam AND foo = :fooparam Unlike the positional styles, the names of the parameters are actually used when the application fills the parameter values.
顧名思義,Oracle Named方式就是‘:’和名字的方式來表示參數,而不是像Oracle Positional用數字.這種方式的好處就是相同的參數可以使用同一個名字,在VO初始化參數的時候對相同名字的參數只用初始化一次就可以了,在下面的實現中會具體介紹.
如何在VO使用Oracle Named綁定方式
首先,我們需要在VO定義介面上進行設定,
1. 在Bind Variable 頁面上定義要在VO SQL Statement中使用的綁定參數的名字,類型和預設值。
2. 在VO SQL Statement頁面上設定Binding Style為 Oracle Named.
3. 在VO SQL Statement 中的where clause裡面使用 ‘:’加上Bind Variable中定義的Bind variable作為參數,比如 :inv_org_id,而且這些參數我們可以使用多次。
在VO定義上設定完之後,我們需要執行VO查詢之前,使用vo.setNamedWhereClauseParam(String name, Object value)對VO的綁定參數進行賦值,如下面的代碼。
public void initRcvSubinventory(String orgId, String itemId, String receiptSourceCode) { RcvSubinventoryLovImpl vo =this.getRcvSubinventoryLov1(); vo.setWhereClause(null); vo.setWhereClauseParams(null); vo.setNamedWhereClauseParam("inv_org_id", orgId); vo.setNamedWhereClauseParam("rcv_item_id", itemId); vo.setNamedWhereClauseParam("receipt_source_code", receiptSourceCode); } |
使用Oracle Named 綁定方式需要注意的問題
1. 在使用Oracle Named綁定方式的時候一定要聲明Bind Variable,如果沒有聲明就在VO SQL Statement中使用,在運行時就會出現下面的錯誤.
(oracle.jbo.SQLStmtException) JBO-27122: SQL error during statement preparation.
## Detail 0 ##
(java.sql.SQLException) Missing IN or OUT parameter at index:: 1
2. 相反,如果定義了Bind Variable, 但是在VO SQL Statement中沒有使用他,或者定義的類型錯誤,在運行時就會拋出下面的錯誤
oracle.jbo.SQLStmtException: JBO-27122: SQL error during statement preparation.
## Detail 0 ##
java.sql.SQLException: Attempt to set a parameter name that does not occur in the
SQL: inv_org_id
3. 如果在定義Bind Variable的時候沒有指定預設值,而且在運行時沒有使用vo.setNamedWhereClauseParam()初始化Bind Variable,那麼Bind Variable預設將會使用NULL值.但一般情況下,NULL不是使用者需要的,請記得設定預設值或者運行時為Bind Variable指定值。
JDBC Positional
這種綁定方式在EBS OAF開發中是不常見的,因為Oracle文檔中是這麼介紹的
This style represents parameters as question marks, as in the following code fragment:WHERE foo = ? AND bar = ?. This should be used only if you are working with non-oracle database.
因為EBS應該沒有使用非ORACLE資料庫的,所以應該在OAF開發中是用不到的,但是在ADF開發中應該是用得到的,但這個不在我們今天討論的範圍之內。