Openbravo开发手册
簡介
Openbravo是一款面向中小企業的純WEB方式的可擴展的ERP軟件。她包括了基本的CRM(客戶關系管理)、BI(商業智能)和一系列如采購、庫存、項目、生產銷售和財務管理等功能。適用于物流、服務和生產制造等多個行業。
Openbravo可以定制以支持特定行業的功能和業務流程。
Opnebravo的許可證允許合作伙伴和開發者選擇是否將自已的工作以開源許可證還是以私有許可證的方式發布。我們鼓勵合作伙伴和開發者以開源的方式與別人共享開發成果,也為Openbravo提供新的內容。本手冊的目的是給大家為客戶定制新的功能提供指導。
開發概述
以下列出了在Openbravo開發中使用的模型驅動開發方法的主要概念:
- 應用字典:集中存放了定義的窗口、頁簽和字段的表。
- 應用菜單:程序左邊的主菜單。
- Callout(類似于觸發器):用戶操作一個窗口時系統響應的動作。例如可以增加或減少可見的字段,或者根據輸入系統的信息填定訂單。
- 表單:手工制作的可以輸入、修改或刪除的窗口。不同于標準窗口,表單允許復雜數據的輸入和在多個位置輸入數據。
- MVC(模型-視圖-控制器):將應用程序的數據、用戶界面和流程分離的一種架構。在Openbravo中MVC是這樣實現的:
-
- 模型部份是用Openbravo的SqlC實現的。通過一個有標準SQL語句和參數的XML文件實現。其中的參數是可選或必須的,可以很容易的生成SQL語句。
-
- 視圖部份是用Openbravo開發的XmlEngine實現的。XmlEngine是可以從一個XML/HTML格式的模板生成XML/HTML文檔的工具。
-
- 控制器是從HttpBaseServlet繼承的子類。這些Servlet處理讀取數據,使用SQLC生成的類與數據庫交互和使用XmlEngine提供輸出。
- 報表:顯示從表中檢索出來的數據或以預定義的格式和可視化的交互方式進行查詢。以pdf或html的方式顯示請求的信息是一種簡捷的方式。報表可以用戶希望的方式進行定制,通常用于展示全局形勢或總結。
- 標準窗口:可以輸入、修改和刪除數據的自動生成的窗口。窗口中的信息是由Openbravo按系統中的數據生成的。
- 窗口:應用程序用于管理數據的屏幕。可以進行插入、更新或刪除數據的操作。Openbravo中有兩種窗口:標準窗口和表單。一個窗口可能會包含多個頁簽。
開發方法
Openbravo是構建Openbravo ERP的開發平臺。正如架構總覽中解釋的開發可以理解為兩層。
應用程序字典。它存儲了應用程序的所有窗口、表、列、進程、報表和它們的關系。用戶只要可以很方便的通過定義一個窗口、數據元素和報表并在應用程序字典中注冊就可以增加一個新的功能,而無需一行代碼。大部份的Openbravo代碼是從應用程序字典中自動生成的。
模型/視圖/控制器。當工作在這個層級時是可以通過Openbravo MVC開發框架完成任何改變的。無論如何一個工具或功能不能通過數據字典調整時,都可以在MVC這個層級實現。這通常意味著要開發一個新的JAVA類。
組織開發工作
在開始開發一個新的功能時必須清楚什么東西必須完成。下面幾點對組織你的開發工作會有所幫助:
- 應該提供哪些功能。必須清楚哪些功能要實現。
- 盡量簡單。保持設計盡量簡單并且能很好的與不同組件進行交互。
- 定義你的數據模型。需要添加哪些表、列、關系和索引來存儲數據以實現想要的功能。
- 定義用戶界面。用戶如何使用新的功能。按工業標準的可用性指南組織可視化的元素。
- 定義報表。考慮哪些數據和你的用戶有關和如何最好的呈現在報表中。
標識符命名標準
數據字典命名制定一個清晰和固定的標準對于ERP系統是非常關鍵的。按照這個命名標準就能保證Openbravo ERP的新版本不會因為與客戶開發時使用的數據字典元素同名而產生沖突。
當自定義開發時,在每一個新的數據字典元素前加上CUS_的前綴。例如,當為一個名為ACME的公司進行客戶定制時,在數據字典元素名前加上CUS_ACM的前綴。
當開發一個垂直功能時,加上這個市場名前加上VER_的前綴。例如,為房地產市場開發時使用VER_REA的前綴。
數據庫元素
命名新的表時加上特定的開發時的前綴。例如你需要為ACME客戶定制開發時需要增加一個DOCUMENT的表時你應該將該表命名為CUS_ACM_DOCUMENT。這些表的字段可以按照字段命名轉換(AD_CLIENT_ID,IsActive,Name,Descriptioin等)。
當在已有的表中增加新的字段時需要加上特定的開發時的前綴。
其他的數據庫對象(存儲過程,觸發器等)也要加上開發時的前綴。
數據字典的注冊IDs是由序列按開發時的順序生成的,因而不會出現重復的IDs。數據字典中的實體名都應加上一定的前綴。
MVC目錄
命名目錄時加上特定的前綴。建議建立一個獨立的包。(org\openbravo\erpCommon\cus_myPackage)。
存儲過程語法
- 作為存儲過程參數的變量名前加上p_的前綴
- 變量名前加v_的前綴
- 游標名前加c_的前綴
目錄結構
Openbravo ERP的目錄結構從邏輯上區分了核心組件(XmlEngine,SQLC,HttpBaseServlet)和WAD(應用程序字典向導)與ERP本身的結構(表單,報表,call-outs,下拉列表,工作流,流程等)。
主樹結構
AppsOpenbravo|-attachment |-build|-config|-database|-docs|-legal|-lib|-src|-srcAD|-srcClient|-src-core|-src-db|-src-trl|-src-trl|-src-wad|-web|-WebContent|-src-locbuild編譯好的類會被復制到這個目錄中
AppsOpenbravo|-build|-classes|-org|-openbravo|-authentication|-basic|-lam|-base|-secureApp|-erpCommon|-erpReports|-erpWindows|-javasqlc|-src|-srcADconfig包含了各種配置和日志文件
AppsOpenbravo|-config|-Format.xml|-log4j.lcf|-Openbravo.properties|-setup-properties-linux.bin|-...database包含模型數據(結構:表,約束,存儲過程和觸發器),示例數據(如產品,業務伙伴等)和XML格式的源數據(窗口和頁簽)。
AppsOpenbravo|-database|-lib|-model|-functions|-sequences|-tables|-triggers|-views|-sampledata|-sourcedatadocsOpenbravo的API文檔,由Javadoc生成。
legal許可證文檔。
lib編譯時需要的庫。
AppsOpenbravo|-lib|-openbravo-core.jar|-openbravo-trl.jar|-openbravo-wad.jar|-openbravo.war|-...openbravo-core.jar,openbravo-trl.jar和openbravo-wad.jar是執行ant compile.complete時必須的。編譯的結果是一個名為openbravo.war的文件,需要將其復制到應用服務器的webapps目錄下。
srcOpenbravo ERP的源代碼:表單,報表,call-outs,combos,工作流,流程等。
AppsOpenbravo|-src|-org|-openbravo|-base|-erpCommon|-ad_actionButton|-ad_background|-ad_callouts|-ad_combos|-ad_forms|-ad_help|-ad_process|-ad_reports|-ad_tasks|-ad_workflow|-businessUtility|-info|-reference|-security|-utility|-ws|-erpReports前綴ad_表示應用程序字典。字典名的結尾說明了它的意思。ad_reports和erpReport的區別在于在應用程序中存取報表的方式不同。如果是通過菜單調用的報表應該放在ad_reports,另一方面,有些窗口在工具欄上有一個打印的按鈕,通過這種方式調用的報表應該放在erpReports。
srcAD保存了通過應用程序字典自動生成的代碼。
srcClient存放為自已應用程序開發的代碼,不是給其他客戶。
src-core核心組件的源代碼:?XmlEngine?(視圖層),?SQLC?(模型層),?HttpBaseServlet?(控制器)和連接池。
AppsOpenbravo|-src-core|-src|-org|-openbravo|-base|-HttpBaseServlet.java|-HttpBaseUtils.java|-data|-Sqlc.java|-database|-ConnectionPool.java|-xmlEnginesrc-db創建dbmanager.jar文件需要的源代碼。
AppsOpenbravo|-src-db|-src|-org|-openbravo|-ddlutilssrc-trl翻譯器的源代碼。
AppsOpenbravo|-src-db|-src|-org|-openbravo|-translatesrc-wadWAD的源代碼。
AppsOpenbravo|-src-db|-src|-org|-openbravo|-wad
webCSS,Javascript的代碼和圖片及彈出窗口。
src-locMVC結構中的視圖層元素結構:HTML,XML,FO和子報表。它們被放在不同的位置(每一種一個目錄)。
AppsOpenbravo|-WebContent|-src-loc|-design|-org|-openbravo|-base|-erpCommon|-erpReports|-erpWindows|-es_ES|-xx_XX|-...風格指南
為了代碼的統一和清晰,我們建議按下面的指南進行編碼。這個指南應用于Java,XML,HTML和PL/SQL。
邏輯比較
不要使用空格。
- 不正確::
WHERE a = b
WHERE a= b
- 正確::
WHERE a=b
逗號分隔列表
- 不正確:
SELECT a,b,c
SELECT a ,b ,c
SELECT a , b , c
- 正確:
SELECT a, b, c
圓括號中的空格
在函數中使用時:
- 不正確:
SELECT max( c1 )
SELECT max (c1)
- 正確:
SELECT max(c1)
在比較操作時:
- 不正確:
if(i==0)
if( i==0)
- 正確:
if (i==0)
for (i=0; i<n; i++)
SELECT INTO和INSERT INTO
如果超過8個字段:將其分為4個一組(為了易讀性)。一行80個字符。這是比較靈活的規則。
SQL關鍵字
SQL的關鍵字要大寫。
- 不正確:
select * from AD_FIELD
- 正確:
SELECT * FROM AD_FIELD (SELECT, UPDATE, 等)
編譯程序
命令行編譯任務
ant core.lib編譯MVC框架的核心組件。它會生成openbravo-core.jar文件。
AppsOpenbravo|-lib|-openbravo-core.jarant wad.lib編譯。它不會生成窗口,只是生成WAD本身而已。它會生成openbravo-wad.jar文件。
AppsOpenbravo|-lib|-openbravo-wad.jarant trl.lib編譯翻譯器。它會生成openbravo-trl.jar。
AppsOpenbravo|-lib|-openbravo-wad.jarant compile.complete編譯整個程序。它會生成WAD的窗口和編譯應用程序的源代碼。它依賴于core.lib,wad.lib和trl.lib。
ant compile.complete.development編譯整個應用程序并復制到tomcat的容器中。它會生成WAD的窗口和編譯應用程序源代碼。它依賴于core.lib,wad.lib和trl.lib。
ant compile -Dtab="xx,yy"生成指定的窗口(名稱中包含xx或yy),編譯修改過的源代碼并且更新web.xml中的servlet-mapping。
ant compile.development?-Dtab="xx,yy"生成指定的窗口(名稱中包含xx或yy),編譯修改過的源代碼并且更新web.xml中的servlet-mapping。最后會將所有生成的類復制到tomcat的容器中。
ant setup調用設置數據庫連接和應用程序路徑的界面(是build.xml中的默認任務)。
ant war在lib目錄下生成一個war文件:
AppsOpenbravo|-lib|-openbravo.warant deploy復制war文件到tomcat的webapps目錄下。
ant installWebService安裝Web Service到應用服務器的目錄。
ant install.source會執行ant core.lib,ant wad.lib,ant trl.lib,ant compile.complete,ant installWebService和ant war任務。這個任務只用于安裝。
開發環境
在開發環境中內容中手工拷貝的。我們不會生成war文件因為這比較耗時。
第一次編譯過程是這樣的:
ant core.lib ant wad.lib ant trl.lib ant compile.complete.development然后編譯整個應用程序:
ant compile.complete.development編譯特定的窗口:
ant compile.development -Dtab="window name"編譯手工代碼:
ant compile.development -Dtab=xx為了編譯時避免執行翻譯的任務(對于這個階段將時間花在這上面是沒有必要的),可以在命令中添加一個參數:-Dtr=no。
ant compile.development -Dtab="window name" -Dtr=no ant compile.development -Dtab=xx -Dtr=no生產環境
在生產環境下應用程序會打包在war文件中。這可以讓我們對每一個應用程序設置正確的權限,但是我們必須將war文件發布到tomcat中,以使它能運行起來。
第一次編譯的過程如下:
ant core.lib ant wad.lib ant trl.lib編譯整個應用程序:
ant compile.complete ant war ant deploy編譯指定的窗口:
ant compile -Dtab="window name" ant war ant deploy編譯手工代碼:
ant compile -Dtab=xx ant war ant deploy從源代碼構建
這一節是如何從源代碼構建的快速指南。你可以在?Build Openbravo from Sources看到完整的步驟。
安裝Subversion
Subversion是一個源碼控制工具,可以讓開發者控制文件的版本。
構建前必須先安裝Subverion。可以從這里下載:
http://subversion.tigris.org?*
必須同時安裝OpenSSL。
現在的源代碼還不支持PostgreSQL只支持Oracle。?Openbravo 2.3?將會支持PostgreSQL。
從Subversion中檢出源代碼
安裝好Subverion后運行如下代碼:
svn co https://openbravo.svn.sourceforge.net/svnroot/openbravo/trunk AppsOpenbravo
將會創建AppsOpenbravo的目錄,源代碼保存的目錄。
快速構建指南
從創建的subversion文件的目錄運行如下命令:
ant -f build.xml.template setup
這個過程會配置安裝參數。
- build.xml被創建
- 在config目錄下創建dbCon5.xml,XmlPool.xml, log4j.lcf和userconfig.xml
- 在src目錄下創建deploy.wsdd
使用Oracle數據庫時所有這些文件都會被創建。如果使用PostgreSQL需要將dbCon5.xml?和XmlPool.xml文件名修改為dbCon5_PostrgreSQL.xml?和XmlPostgreSQL.xml。
當參數按上面的方式配置好后,再運行下面的命令。
ant install.source
這個過程編譯并生成應用程序的jar文件并在lib目錄下生成openbravo.war文件。需要將些文件復制到$CATALINA_HOME/webapps?目錄以發布應用。
集成開發環境
一些快速入門以Eclipse來開發Openbravo ERP,可以參考以下鏈接:
Openbravo數據模型
存儲的數據庫對象
某些情況不在Openbravo中的數據庫對象(存儲過程,函數和觸發器)必須符合指定的規則才能使用。應用程序中存儲過程時只能通過對應的AD_PInstance_ID來調用。存儲過程也必須正確的管理AD_PInstance,設置返回值、設置有用的輸出信息。在創建存儲過程這一節會更詳細的介紹如何開發一個存儲過程。
實體-關系(ER)圖
Openbravo的實體-關系數據庫圖展示了Openbravo整個的數據模型。它包括了Openbravo ERP的功能所使用的所有表和字段。
根據應用程序字典中的數據生成了文檔。這些圖按不同的主功能模塊分成了幾個章節。同一個表可能在不同的章節中出現但具體的描述只出現一次。這樣做是為了強調某一個章節中主要的表與其他章節中表的關系。例子中展現了所有的關系但沒有代表性的表不會出現在章節中。
創建存儲過程
AD_PInstance和AD_PInstance_Para表
應用程序中調用存儲過程都需要在表AD_PInstance中注冊。表AD_PInstance_Para中存放了報表和流程窗口中相應的存儲過程的參數的值。
表AD_PInstance:
- AD_PInstance_ID:表的標識符。
- AD_Process_ID:與在應用程序字典中存放存儲過程信息的表AD_Process相關聯的外鍵。
- Record_ID:如果在窗口中調用存儲過程,這一列存放當前記錄的ID。
- IsProcessing:存儲過程在執行中時這一列為“Y”。有些存儲過程會檢查相關的存儲過程是否正在運行。
- AD_User_ID:調用存儲過程的用戶ID。
- Result:存放存儲過程運行的結果。
- ErrorMsg:存放存儲過程輸出的信息。
表AD_PInstance_Para:
- Parametername:對應于數據庫列名的參數名稱。
- P_String和P_String_TO:當字段是文本框或列表框時插入的值。
- P_Number和P_Number_TO:當字段是數字框或外鍵時插入的值。
- P_Date和P_Date_TO:當字段是日期型時插入的值。
- Info和Info_TO:
當參數定義為一個范圍內的值而不是指定的一個值時用_TO的后綴。使用這個參數生成的彈出窗口會有兩個標簽為From和To的字段。之后可以按其中的值來過濾查詢結果。
存儲過程的輸入參數
應用程序調用存儲過程時僅傳遞一個參數到數據庫,就是對應的AD_PInstance_ID。
我們需要一個中介存儲過程來從應用程序或一個不同的存儲過程來調用另一個存儲過程。因為從一個存儲過程調用另一個存儲過程時是不知道AD_PInstance_ID的。可以參考C_Order_Post和C_Order_Post1。主存儲過程調用時需要有足夠的參數,包括AD_PInstance_ID。被調用的中介存儲過程僅有一個關于AD_PInstance的參數。這個存儲過程僅有一個到主存儲過程的調用,其中除了AD_PInstance其余參數都是空的。在主存儲過程中必須區分AD_PInstance是否為空來管理調用的結果和輸出信息。
從AD_PInstance表中獲取有用的信息
在存儲過程的開始我們也許會想要從AD_PInstance和AD_PInstance_Para兩個表中知道一些必須的信息保存到變量中。如果沒有參數那么用SELECT就可以了。如果有多個參數那么可能需要使用游標。參見C_Debt_Payment_Create。
Record_ID存放窗口中當前的活動記錄的ID(如當處理Order時的C_Order_ID)。如果存儲過程中有Update或Insert子句,AD_User_ID可以用于驗證用戶權限。
AD_Update_PInstance存儲過程
該存儲過程用于更新AD_PInstance的狀態。其他存儲過程必須在開始和結束時調用該存儲過程。
參數:
- p_PInstance_ID:將要被更新的AD_PInstance_ID。
- p_AD_User_ID:執行更新的AD_User_ID。
- p_IsProcessing:存儲過程的狀態。
- p_Result:存儲過程的結果。
- p_Message:存儲過程的輸出信息。
在開始調用時設置Processing='Y':
AD_UPDATE_PINSTANCE(p_PInstance,NULL,'Y',NULL,NULL);在結整調用或引發例外時需要設置Processing='N'和相應的執行結果和輸出信息:
AD_UPDATE_PINSTANCE(p_PInstance_ID,v_User,'N',v_Result,v_Message);存儲過程執行的結果有3種。按不同的結果會顯示不同的包含輸出信息的對話框。結果為0表示錯誤(紅色對話框),1表示成功(綠色對話框)和2表示警告(黃色對話框)。如果輸出信息是NULL將作為成功來處理。
例外和錯誤管理
存儲過程的錯誤信息只能依靠對應的AD_PInstance的結果來管理。所以所有的例外必須被正確的處理。
當在存儲過程中觸發了RAISE_APPLICATION_ERROR的例外時,錯誤號被設置為-20000。同時你可以加上對該問題的錯誤描述。描述信息中可以使用存儲在AD_Message表中的信息,只要將它的值放在@之間。也可以將多個字符串連接在一起。
例外塊中必須能夠區分兩種不同情況:存儲過程是被應用程序直接調用還是被其他存儲過程調用的。通常這可以通過AD_PInstance_ID是否為NULL來區分。
如果是由其他存儲過程調用時引發的例外是由存在于AD_PInstance中的父存儲過程處理的。但是這不適用于以上介紹的中介存儲過程。因為中介存儲過程中沒有處理例外的塊,所以還是由相應的AD_PInstance_ID的主存儲過程來處理。在RAISE 之前可以使用DBMS_OUTPUT.PUT_LINE()用于調試。下面是被另外一個存儲過程調用的存儲過程中的例個塊的例子:
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('ERROR MA_Standard_Cost_Sequence, sequence_ID '|| p_Sequence_ID || ', date ' || p_CalcDate || ' at ' ||v_ResultStr);RAISE;END Ma_Standard_Cost_Sequence;如果存在AD_PInstance時例外必須要在AD_PInstance表中設置對應的信息。這條信息是由@ERROR=SQLERRM組成的,SQLERRM中是在RAISE_APPLICATION_ERROR或數據庫拋出的的例外中的錯誤信息。然后是調用ROLLBACK,最后在AD_PInstance中更新錯誤信息并返回結果為0、顯示錯誤信息的對話框。同時也可以使用DBMS_OUTPUT.PUT_LINE()用于測試。
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE(v_ResultStr)?;v_ResultStr:= '@ERROR=' || SQLERRM; DBMS_OUTPUT.PUT_LINE(v_ResultStr)?;ROLLBACK;AD_UPDATE_PINSTANCE(p_PInstance_ID, NULL, 'N', 0, v_ResultStr)?;RETURN;END MA_ProductionRun_Standard;存儲過程語法的建議
Openbravo支持Oracle和PostgreSQL數據庫。
以下的一些建議可以使你的存儲過程能同時在這兩個數據庫上運行或能夠很容易的轉換。這里假設你已經為Oracle與了代碼但同時想讓這些代碼能在PostgreSQL上運行。
通用規則
以下一些內容能確保PL代碼能正確地在其他數據庫后臺運行。
- JOIN語句。用LEFT JOIN或RIGHT JOIN代替(+)
- 在XSQL中使用問號(?)作為參數據占位符。如果參數時數值型使用TO_NUMBER(?),日期型使用TO_DATE(?)。
- 不要使用GOTO語句,因為PostgreSQL不支持GOTO。
- 使用COALESCE代替NVL
- 使用CASE代替DECODE。如果CASE 表達式為NULL,如:
- 如果變量的值是幾個字符串連接起來的要用括號括起來
- 用NOW()代替SYSDATE
- PostgreSQL區分""和NULL,在檢查空變量的時候要注意這一點
- 使用子查詢時要加上別名。
- 使用SELECT語句時總是使用AS
- PostgreSQL中UPATE,INSERT,和DELETE語句中不支持別名。
- PostgreSQL8.1不支持這樣的UPDATE語句(但8.2已支持了)
但下面的語句是可以的:
- PostgreSQL不支持在更新的字段中加上表名。
- PostgreSQL不支持DELETE TABLE,可以使作DELETE FROM
- PostgreSQL不支持在ORDER BY或GROUP BY中使用參數,如‘1’。而沒有引號的數字是可以的。
- PostgreSQL不支持CURRENT OF語句。
- PostgreSQL不支持COMMIT。它會在BEGIN和END塊間自動顯示的提交。拋出例外時會產生ROLLBACK。
- PostgreSQL不支持SAVEPOINT。可以用BEGIN,END和ROLLBACK完成同樣的功能。
- PostgreSQL不支持CONNECT。
- PostgreSQL和Oracle都不支持用變量來指定表的字段名稱。如使用v_IsProcessing替代IsProcessing。
- PostgreSQL不支持EXECUTE IMMEDIATE...USING。可以使用SELECT和參數來完成相同的功能。
- PostgreSQL在調用沒有參數據函數時要加上括號。
- DBMS.OUTPUT應該在一行內,以使自動翻譯可用。
- 在PostgreSQL中任何字符串與NULL連接都會產生一個NULL的字符串。建議用COALESCE或將變量初始化為‘’。
-
- 注意:在Oracle中null||'a'結果是'a',而在PostgreSQL中結果是NULL,所以應使用coalesce(null,)||'a'。但時如果變量是Oracle的NVarchar類型時會引發ORA-12704:字符集不匹配的錯誤,這時可以這樣做coalesce(to_char(myNVarCharVariable),)||'a'。
將以下語法
COALESCE(variable_integer, '')用
COALESCE(variable_integer, 0)來代替,以保證可以在PostgreSQL中也可以運行。
- PostgreSQL執行SELECT FOR UPDATE是在表級而Oracle是在列級別。
- PostgreSQL不支持帶有三個參數的INSTR命令,可以使用SUBSTR。
- 在Oracle中SUBSTR(text,0,Y)和SUBSTR(text,1,Y)的結果是相同的,但是PostgreSQL中不同。所以要使用SUBSTR(text,1,Y)。
- PostgreSQL不支持這樣<<LABEL>>的標簽。
- 在日期比較中默認的日期是1900.1.1或9999.12.31。
- 如要將日期類型轉換為文本型時要使用to_date函數和相應的掩碼。
如:
COALESCE(movementdate, TO_DATE('01-01-1900', 'DD-MM-YYYY'))游標
有兩種使用游標的方法:FETCH子句和FOR循環。
Oracle中FETCH游標的聲明:
CURSOR Cur_SR ISPostgreSQL中:
DECLARE Cur_SR CURSOR FORFOR循環中的游標格式:
TYPE RECORD IS REF CURSOR;Cur_Name RECORD;這在Oracle和PostgreSQL中都可以使用。
數組
在Oracle中數組是這樣定義的:
TYPE ArrayPesos IS VARRAY(10) OF INTEGER;v_pesos ArrayPesos; v_dc2?:= v_dc2 + v_pesos(v_contador)*v_digito;但在PostgreSQL中是這樣定義的:
v_pesos integer[]; v_dc2?:= v_dc2 + v_pesos[v_contador]*v_digito;ROWNUM
為了限制SELECT語句返回的行數,需要創建游標來讀取記錄。代碼如下:
--Initialize counter v_counter?:= initial_value; --Create the cursor FOR CUR_ROWNUM IN (SELECT CLAUSE) LOOP-- Some sentences--Increment the counterv_counter?:= v_counter + 1;--Validate conditionIF (v_counter = condition_value) THENEXIT;END IF; END LOOP;%ROWCOUNT
SQL%ROWCOUNT不能直接在PostgreSQL中使用,而需要定義一個變量。如:
GET DIAGNOSTICS rowcount?:= ROW_COUNT;用上面定義的變量來替換SQL%ROWCOUNT。
%ISOPEN,%NOTFOUND
PostgreSQL不支持%ISOPEN和%NOTFOUND,但可以在存儲過程內部定義一個boolean變量,然后當游標打開或關閉時手工去更新這個變量的值。
表
當定義表時,如果列名是關鍵字要用用引號引起來。如:
CREATE TABLE AD_TRACE ("WHEN" TIMESTAMP NOT NULL,NO NUMERIC DEFAULT 0 NOT NULL,WHAT VARCHAR(2000) NOT NULL );列WHEN用引號引起來以避免轉到PostgreSQL后出現問題。
同樣在約束、解發器、存儲過程、視圖和函數中也要這樣處理。
函數
可以使用PERFORM和SELECT調用函數。因為PostgreSQL不支持默認參數,可以定義一個帶有默認參數的重載函數。
另外如果要使自動翻譯能正常工作,你應該遵循以下的建議:
- AS和IS的左邊不能有空格
- 函數名不能用引號
- 函數中,END前不能有空格。
存儲過程
在PostgreSQL中有兩種方法調用存儲過程:
- 變量名:=存儲過程名(...)
- 使用SELECT。這種方法用于存儲過程返回多個參數時使用。
視圖
PostgreSQL不支持可更新視圖。如果要通過視圖更新要創建一系列的規則。
在PostgreSQL中沒有USER_TABLES和USER_TAB_COLUMNS。應該根據PostgreSQL的pg_class或pg_attribute表來創建。
觸發器
觸發器的規則如下:
- 通常來說,父表中的觸發器不應該修改子表中的列,因為子表中的觸發器經常會參考父表中的數據,否則會引起mutating table的錯誤。
- 觸發器的名稱不要用引號引起來,否則PostgreSQL會作為文本處理。
- 所有的觸發器都要有DECLARE在合法的注釋前。
- PostgreSQL不支持延遲計算值。如下面的語句在Oracle中可以運行但不能在PostgreSQL中運行:
正確的方法是:
IF INSERTING THEN ... IF UPDATING THEN IF?:OLD.NAME = '' THENPostgreSQL中總會有返回值。按不同的操作類型分別返回OLD(DELETE)或NEW(INSERT/UPDATE)。
如果使用自動翻譯應注意:
- 最后一個EXCEPTION的左邊不能有空格。自動翻譯者用最后一個EXCEPTION來設置返回值。
- 最后一個END的左邊不能有空格。縮排用于決定函數據結束。
序列數
PostgreSQL中的bigInts類型是18位的。將
sequence_name.NEXTVAL用
nextval("sequence_name")代替。如果是使用自動轉換,這個會自動的修改。
命令
下面列出了從Oracle轉換到PostgreSQL時要修改的語句:
Oracle PostgreSQL
| SQLCODE | SQLSTATE |
| RAISE; | RAISE EXCEPTION?; |
| RAISE_APPLICATION_ERROR | RAISE ERROR?; |
| DBMS.OUTPUT | RAISE NOTICE '%' |
| ROWNUM | LIMIT |
| MINUS | EXCEPT |
| ISREFCURSOR | REFCURSOR |
| EXECUTE IMMEDIATE | EXECUTE |
| EXCEPTION NO_DATA_FOUND | EXCEPTION DATA EXCEPTION |
| COMMIT | ? |
| ROLLBACK | RAISE EXCEPTION |
支持PostgreSQL8.3
為了支持PostgreSQL8.3,Openbravo2.40alpha已經調整了源代碼。為了兼容這個版本的PostgreSQL,最大的修改是非字符數據不再自動轉換為TEXT類型。
之前,如果提供一個非字符型的值給一個需要字符型參數的函數或一個操作時會自動轉換為字符型,大部份(不是所有)的內建類型都是這樣處理的。對于這種情況現在都需要進行顯示的類型轉換。例如,以下表達式之前是可以運行的:
substr(current_date, 1, 4) 23 LIKE '2%'但現在會提示“函數不存在”或“操作不存在”的錯誤。需要進行顯示的類型轉換:
substr(current_date::text, 1, 4) 23::text LIKE '2%'(當然你也可以使用CAST())。這樣修改的原因是因為這些自動類型轉換經常會引起一些無法預知的錯誤。如在以前的版本中,下面的表達式是語法正確的但運行的結果不是預期的:
current_date < 2017-11-17這實際上是日期型與整型的比較,不應該拒絕這樣的操作(現在已經是拒絕了)。但是在以前這樣的表達式會轉換成字符型與字符型比較。
但char(n)和varchar(n)仍然會自動轉換成TEXT類型。盡管字符串連接(||)操作符仍然會進行自動類型轉換,但至少其中一個操作符應該是字符型的。
因為以上的原因,PostgreSQL8.3在存儲過程和數據庫源代碼文件中都要求進行顯示的類型轉換。這個大范圍的修改已經在Openbravo2.4alpha中完成。例如,下面的表達式可以在Oracle/PostgreSQL中正確運行:
substr(TO_CHAR(current_date), 1, 4) TO_CHAR(23) LIKE '2%'Openbravo的源代碼和存儲過程中已經做了許多類型顯示轉換的操作以支持PostgreSQL8.3。主要的修改是:
- 函數的類型轉換:當在PostgreSQL中調用函數時,參數必須匹配。一個典型的例子是在XSQL文件中的AD_COLUMN_IDENTIFIER函數,在存儲過程中也是同樣處理的。
- 操作時的類型轉換:例如傳遞一個數字時作為標識符或日期到SQL語句:
只要進行這些修改就可以兼容PostgreSQL。 Openbravo2.4alpha已經通過了與PostgreSQL8.3的可接受測試。
修飾名稱和描述內容的指南
說明內容的修辭指南
Openbravo在數據字典中的字段描述主要有兩個目的:
- 直接說明了字段如何使用的
- 一些附加的信息
在閱讀本節前,要知道在Openbravo ERP中已經有超過5000個的例子。強烈建議在需要時參考已存在的例子。
- 時態:最好使用現在時,如果有必要可以使用過去時。
- 人稱:
- Windows和Tabs:第二人稱
- 元素:第三人稱(其實是要避免我,你,他或她都混在一起)
- 單/復數:
- Windows和Tabs:用復數
- 元素:用單數
- A/n vs The:當指一般的東西時用A,當指特定的東西時用The。
- 僅用下面的某一項來描述Window/Tab的結構
- View-僅用于某些只讀的內容時
- Create-當需要創建新的內容時使用,并且可以修改
- Add-當一些內容之前已經輸入過,但之后可以修改的情況
- Edit-當需要修改信息時
- Define-當需要在設置區域中輸入數據,并且不是為了事務性的目的
- Import-導入數據時
- Translate-進行轉換時
create和edit,add和edit,define和edit可以組合使用。
- 描述的長度一般在20個單詞左右
有一些詞不允許在應用程序中作為描述使用。
Out In
| Generate | Create, Add, or Edit |
| Manage | Create, Add, or Edit |
| Assign | Create, Add, or Edit |
| Apply | Create, Add, or Edit |
| Assign | Create, Add, or Edit |
| Apply | Create, Add, or Edit |
| New | x (redundant) |
| Different | x |
| Variety | x |
| Various | x |
| Period of time | Time period |
| Given, Scheduled, Chosen (time period) | Specified |
命名的修辭指南
名稱的修辭(如,名稱,地址,城市)對于每條記錄都是一樣的。一般是用戶或顧問使用這些名稱。包括如下內容:列、元素名稱、字段分組、字段名、列表、菜單、消息、過程、過程的參數、參考、表、頁簽、文本的接口和窗口。
可以參考The Data Model Resource Book by Silverston?這本書。
- 可接受單復數
- 大寫關鍵字
在設置中,請使用單數。
- 動詞
Window或Tab的名稱不要用動詞開頭 Processes總是以動詞開頭
- 縮寫
"Quantity"不縮寫 "Number"一般縮寫為"no." 一般不使用縮寫
- 做下面的操作時要慎重
名稱中加入-,/,# 用"ed"結尾不能為了清楚,簡單的區分產品而在應用程序中使用相關的單詞。
- 使用“Header"和"Line"作為Tab的名稱
有時用戶需要知道該用什么詞:
Term Described Synonym
| Set | Group |
| Total | (summary of all), final |
| Charge | Expense or Expenditure |
| Planned | Expected |
| Plan | Strategy, Structure |
| Schedule | Dates, Times |
| Setup | Structure |
| Type | Distinct characteristic |
| Date | Period or time |
| Cost | Charge |
| Amount | Monetary sum |
| Quantity | Number |
| Key | Identification code |
| From/To | Range (unless specified) |
| Price | Value |
| Account | Identification code |
| Number (no.) | Specific number or code |
有些單詞不可以使用:
Out In
| System | Application |
| Group | Category or Set |
| Rule | Setup |
| "Is" | x (no verb starters) |
總的來說,Openbravo建議根據具體情況使用現有的描述。
使用數據字典進行Openbravo的開發
這一節介紹了如何使用應用程序字典(AD)來開發Openbravo ERP。我們將通過一個例子來一步一步的展示開發過程。這個例子包括一個新的文檔注冊功能和一些新的數據庫元素,如窗口和報表。
擴展數據模型
首先,使用數據庫管理工具建立一個新的表。(如用于PostgreSQL的pgAdmin III或phpPgAdmin以及用于Oracle的Oracle SQL Developer或Toad)。使用安裝時的數據庫連接參數以正確的連接數據庫實例。
在數據庫中創建新的表
建立一個新的表CUS_DOCUMENTS包括這些字段AD_Client_ID,?AD_Org_ID,?IsActive,?Created,?CreatedBy,Updated?和UpdatedBy?,因為這些字段是安全認證所必須的。
Column name Type Length
| CUS_DOCUMENTS_ID | NUMBER | 10 |
| AD_CLIENT_ID | NUMBER | 10 |
| AD_ORG_ID | NUMBER | 10 |
| ISACTIVE | CHAR | 1 |
| CREATED | DATE | ? |
| CREATEDBY | NUMBER | 10 |
| UPDATED | DATE | ? |
| UPDATEDBY | NUMBER | 10 |
| NAME | CHAR | 60 |
| LASTEDITED | DATE | ? |
| DOCSIZE | NUMBER | 15 |
在這個表中,即使NAME和LASTEDITED可以組成關鍵字,但也請使用另外一個字段作為唯一性的關鍵字如CUS_DOCUMENT_ID。按命名的規則,關鍵字時由表名加上"_ID"組成。
執行下面的SQL語句來建立CUS_DOCUMENT:
Oracle
CREATE TABLE CUS_DOCUMENTS (CUS_DOCUMENTS_ID NUMBER(10) NOT NULL,AD_CLIENT_ID NUMBER(10) NOT NULL,AD_ORG_ID NUMBER(10) NOT NULL,ISACTIVE CHAR(1 BYTE) DEFAULT 'Y' NOT NULL,CREATED DATE DEFAULT SYSDATE NOT NULL,CREATEDBY NUMBER(10) NOT NULL,UPDATED DATE DEFAULT SYSDATE NOT NULL,UPDATEDBY NUMBER(10) NOT NULL,NAME NVARCHAR2(60) NOT NULL,LASTEDITED DATE NOT NULL,DOCSIZE NUMBER(15) NOT NULL,CONSTRAINT "CUS_DOCUMENTS_KEY" PRIMARY KEY ("CUS_DOCUMENTS_ID") );PostgreSQL
CREATE TABLE cus_documents (cus_documents_id numeric(10) NOT NULL,ad_client_id numeric(10) NOT NULL,ad_org_id numeric(10) NOT NULL,isactive char(1) NOT NULL DEFAULT 'Y'::bpchar,created timestamp NOT NULL DEFAULT now(),createdby numeric(10) NOT NULL,updated timestamp NOT NULL DEFAULT now(),updatedby numeric(10) NOT NULL,name varchar(60) NOT NULL,lastedited timestamp NOT NULL DEFAULT now(),docsize numeric(10) NOT NULL,CONSTRAINT cus_documents_key PRIMARY KEY (cus_documents_id) );在Openbravo ERP中注冊新的表
下面的步驟介紹如何在Openbravo ERP的應用程序字典中注冊新建的表。首先,要以具有System Administrator角色的帳戶登錄系統。進入菜單Application Dictionary > Tables and Columns建立一條Name?Cus_documents, Description?Documents to be saved, Help/Comments?Window used to register documents, DB Table NameCUS_DOCUMENTS, Data Access Level?Client/Organization?and Development Status?Ready的新記錄。
?窗口中的主要字段是:
- Name定義Openbravo ERP可以識別表的名稱。
- Description簡短的說明。
- Help/Comments幫助窗口中顯示的內容。
- DB Table name數據庫中的表名稱。
按Create columns from DB?按鈕保存記錄并且自動創建列實體。
?創建完成時,系統會提示有多少列被加到表中了。
?創建新窗口
編譯新窗口
在Openbravo中增加新窗口的菜單
更新數據庫的XML文件
用戶消息
總結
以上是生活随笔為你收集整理的Openbravo开发手册的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开始博客之旅
- 下一篇: [转载]使用 Apache Geroni