Oracle EBS Forms开发指南(中级)_第1页
Oracle EBS Forms开发指南(中级)_第2页
Oracle EBS Forms开发指南(中级)_第3页
Oracle EBS Forms开发指南(中级)_第4页
Oracle EBS Forms开发指南(中级)_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、信息技术最正确实践ORACLE核心应用技术E-Business SuiteForms开发指南Author:黄建华Creation Date:createdate MMMM d, yyyyOctober 16, 2006Last Updated:savedate MMMM d, yyyyFebruary 19, 2021Document Ref: Version:DRAFT 1AApprovals:autotext PIC Oracle Logo * Mergeformat autotext PIC Oracle Logo * Mergeformat autotext PIC Oracle Lo

2、go * Mergeformat Copy Number_Document ControlChange Record SECTIONDateAuthorVersionChange Reference CREATEDATE d-MMM-yy 16-Oct-06Draft 1aNo Previous DocumentReviewersNamePositionDistributionCopy No.NameLocationLibrary MasterProject LibraryProject ManagerNote To Holders:If you receive an electronic c

3、opy of this document and print it out, please write your name on the equivalent of the cover page, for document control purposes.If you receive a hard copy of this document, please write your name on the front cover, for document control purposes.Contents TOC o 2-3 Document Control PAGEREF _Toc22297

4、9806 h ii1.Folder、JTF Grid PAGEREF _Toc222979807 h 21.1.Folder开发步骤从头开始 PAGEREF _Toc222979808 h 21.2.Folder问题 PAGEREF _Toc222979809 h 71.3.Folder开发步骤基于模版 PAGEREF _Toc222979810 h 71.4.JTF Grid开发步骤 PAGEREF _Toc222979811 h 102.多语言开发 PAGEREF _Toc222979812 h 142.1.国际化支持 PAGEREF _Toc222979813 h 142.2.Form自

5、身的多语言版本 PAGEREF _Toc222979814 h 142.3.数据多语言开发步骤 PAGEREF _Toc222979815 h 142.4.EBS启用新语言时的考虑 PAGEREF _Toc222979816 h 223.附件开发 PAGEREF _Toc222979817 h 243.1.关于附件 PAGEREF _Toc222979818 h 243.2.标准附件设置 PAGEREF _Toc222979819 h 244.Javabean PAGEREF _Toc222979820 h 294.1.Form与Java PAGEREF _Toc222979821 h 294

6、.2.例子:Hello World PAGEREF _Toc222979822 h 314.3.例子:执行PC本地命令 PAGEREF _Toc222979823 h 344.4.例子:读取PC文本文件 PAGEREF _Toc222979824 h 374.5.例子:通用导入 PAGEREF _Toc222979825 h 405.Form个性化 PAGEREF _Toc222979826 h 415.1.Form个性化概述 PAGEREF _Toc222979827 h 415.2.例子:修改字段Prompt PAGEREF _Toc222979828 h 425.3.例子:有条件显示消息

7、 PAGEREF _Toc222979829 h 435.4.例子:调用数据库Package PAGEREF _Toc222979830 h 445.5.例子:添加菜单 PAGEREF _Toc222979831 h 445.6.例子:翻开功能 PAGEREF _Toc222979832 h 455.7.例子:执行查询 PAGEREF _Toc222979833 h 465.8.例子:其他应用 PAGEREF _Toc222979834 h 475.9.例子:Instance间迁移 PAGEREF _Toc222979835 h 486.技巧、常用代码 PAGEREF _Toc22297983

8、6 h 496.1.Form中的变量 PAGEREF _Toc222979837 h 496.2.初始值、格式掩码 PAGEREF _Toc222979838 h 496.3.消息处理 PAGEREF _Toc222979839 h 506.4.Special菜单 PAGEREF _Toc222979840 h 506.5.库存组织访问 PAGEREF _Toc222979841 h 506.6.MFG_ORGANIZATION_ID相关问题 PAGEREF _Toc222979842 h 516.7.常用内置过程 PAGEREF _Toc222979843 h 526.8.待续 PAGERE

9、F _Toc222979844 h 527.Open and Closed Issues for this Deliverable PAGEREF _Toc222979845 h 53Open Issues PAGEREF _Toc222979846 h 53Closed Issues PAGEREF _Toc222979847 h 53Folder、JTF GridFolder开发步骤从头开始本节标题说明:标准指做Folder都要做而且是一样的步骤,可以考虑做个模版了;普通指和做普通Form一样;特殊指做Folder都要做但需要根据实际内容作修改。什么是FolderFolder不是Form的

10、标准功能,而是Oracle自己在EBS开发中总结出来的“动态界面:不同用户可以根据自己的需要,设置块中哪些字段需要显示以及顺序;而开发人员那么免于被布局折腾的痛苦。对于开发来说,要做的事情就是用“遵循Folder标准换取“布局零工作量。拷贝标准Folder对象标准翻开,把对象组“STANDARD_FOLDER拖到我们自己的Form中,并选择“Subclass而非“Copy,这个和前面讲的查询块不同。这样会自动产生一系列用于Folder的对象:块、画布、Lov/记录组、参数、Property Classes、Window,这些都不用修改。引用Folder的PLL库标准选中Attached Lib

11、raries,点击“+,如果本地没有请先从效劳器下载。点击Attach后选择“Yes移除绝对路径。创立数据库对象普通创立数据库对象,没有任何特殊之处:- Create tablecreate table SCF.CUX_FLODER_DEMO( FLODER_DEMO_ID NUMBER not null, NUMBER_FIELD1 NUMBER not null, NUMBER_FIELD2 NUMBER, NUMBER_FIELD3 NUMBER, NUMBER_FIELD4 NUMBER, DATE_FIELD1 DATE NOT NULL, DATE_FIELD2 DATE, VAR

12、CHAR2_FIELD1 VARCHAR2(100) NOT NULL, VARCHAR2_FIELD2 VARCHAR2(100), VARCHAR2_FIELD3 VARCHAR2(100), VARCHAR2_FIELD4 VARCHAR2(100), VARCHAR2_FIELD5 VARCHAR2(100), VARCHAR2_FIELD6 VARCHAR2(100), CREATION_DATE DATE not null, CREATED_BY NUMBER not null, LAST_UPDATED_BY NUMBER not null, LAST_UPDATE_DATE D

13、ATE not null, LAST_UPDATE_LOGIN NUMBER, ATTRIBUTE_CATEGORY VARCHAR2(30), ATTRIBUTE1 VARCHAR2(240), ATTRIBUTE2 VARCHAR2(240), ATTRIBUTE3 VARCHAR2(240), ATTRIBUTE4 VARCHAR2(240), ATTRIBUTE5 VARCHAR2(240), ATTRIBUTE6 VARCHAR2(240), ATTRIBUTE7 VARCHAR2(240), ATTRIBUTE8 VARCHAR2(240), ATTRIBUTE9 VARCHAR2

14、(240), ATTRIBUTE10 VARCHAR2(240), ATTRIBUTE11 VARCHAR2(240), ATTRIBUTE12 VARCHAR2(240), ATTRIBUTE13 VARCHAR2(240), ATTRIBUTE14 VARCHAR2(240), ATTRIBUTE15 VARCHAR2(240)tablespace SCF;- Create/Recreate indexes create unique index SCF.CUX_FLODER_DEMO_U1 on SCF.CUX_FLODER_DEMO (FLODER_DEMO_ID) tablespac

15、e SCF; - Create/Recreate sequenceCREATE SEQUENCE SCF.CUX_FLODER_DEMO_S;- Create/Recreate synonumCREATE SYNONYM CUX_FLODER_DEMO_S FOR scf.CUX_FLODER_DEMO_S;CREATE SYNONYM CUX_FLODER_DEMO FOR scf.CUX_FLODER_DEMO;创立Folder块普通按照普通步骤创立数据块,包括块和字段的子类、LOV、On-XXX触发器、行指示符等等,如果有弹性域,那么也需要DF字段和相关的触发器。当然了,从Templat

16、e开始的常规修改步骤也是要做的。为标准起见,块名后加“FOLDER,这里是“DEMO_FOLDER,这种数据块我们叫“Folder块。修改Folder块标准创立SWITCHER字段手工添加字段,名字叫FOLDER_SWITCHER,子类为SWITCHER:并编写触发器WHEN-NEW-ITEM-INSTANCE:app_folder_move_cursor(1);编写触发器需要编写如下触发器:WHEN-NEW-RECORD-INSTANCEWHEN-NEW-BLOCK-INSTANCEPRE-QUERYPOST-QUERYPRE-BLOCKPOST-BLOCKKEY-ENTQRYKEY-EXE

17、QRYKEY-PREV-ITEMKEY-NEXT-ITEMKEY-PRVRECKEY-NXTRECKEY-CLRRECKEY-CLRBLK这些触发器的内容都是app_folder.event(触发器名称);创立Prompt块标准手工创立非数据库块,子类仍为Block,为标准起见,块名后加“PROMPT,这里是“DEMO_PROMPT,这种数据块我们叫“Prompt块。手工创立6个标准Item,名字和子类必须同下表:NameSubclassFOLDER_TITLEDYNAMIC_TITLEFOLDER_OPENFOLDER_OPENFOLDER_DUMMYFOLDER_DUMMYORDER_BY

18、1FOLDER_ORDERBYORDER_BY2FOLDER_ORDERBYORDER_BY3FOLDER_ORDERBY修改Prompt块和Folder块特殊“Folder块有多少字段要显示,就需要在“Prompt块创立多少同名字段除了SWITCHER字段、行指示符、DF字段,前者是Folder的特殊字段,后两者通常需要固定在内容画布上,并设置这些字段的关键属性:属性值SubclassFOLDER_PROMPT_MULTIROWInitial Value字段的PromptWidth字段的宽度,根据实际需要调整Prompt注:清空对“Folder块的字段,也需要清空Prompt属性。理解Fol

19、der自动布局原理到这里,我们先理解下Folder是如何自动布局的:需要使用Folder功能的字段必须放在堆叠画布上,Folder功能仅自动布局堆叠画布宽度和在其上的字段顺序。放在内容画布上的所有对象,包括堆叠画布自身在内容画布上的起始位置,需要我们和以前一样手工调整布局;只要布局得当,一个Windows上可以有多个Folder。自动布局的堆叠画布宽度 = 内容画布宽度 堆叠画布的X座标 0.26,这个0.26啊,正好可以让我们放垂直滚动条!此外,堆叠画布高度也会被自动调整,调整时系统自动回算上水平滚动条的位置!最终界面的字段顺序由Prompt块字段的顺序决定,那么Folder块的字段在界面的

20、排列顺序如何自动和Prompt对应起来呢?原来系统是根据字段名!最终界面Tab键导航的顺序仍然由Folder块字段的顺序决定,所以设计时注意两者要一致。系统并不自动决定字段的Y轴位置!Y,即等于Prompt块的Item的高度。为操作方便,也为了标准化,通常需要放个文件夹按钮在内容画布的左上角,这个就是Folder_Open字段。创立堆叠画布、内容画布、窗口普通Floder要求字段放置在堆叠画布上,为标准起见,画布名后加“FOLDER_STACK,View和Canvas的宽度无所谓,运行时将自定根据窗口的大小调整,右边正好会留出滚动条的位置。另外,为标准起见,内容画布后也可加“FOLDER_CO

21、NTENT。设置这两个画布的子类,并设置它们的Windows属性相同。布局Item到画布特殊设置如下Item到画布:把FOLDER_OPEN、FOLDER_DUMMY、行指示符、Folder块的垂直滚动条,都设到内容画布上,并设计它们的位置。Folder_Open按照其子类默认值即可:X为0.1、Y为0。行指示符。垂直滚动条的Y为0.5,X那么需要在Window的Resize事件中设置,还记得那个0.26吗?这样,堆叠画布在内容画布上的位置,应该就是X为0.2,Y为0.25,想想为什么。同时启用堆叠画布的水平滚动条。Folder块的SWITCHER字段设置到堆叠画布。Folder块的其他需要显

22、示的字段都设置到堆叠画布。Prompt块的其他字段全部设置到堆叠画布,并且Y座标为0。注:FOLDER_TITLE字段不知道是干什么的,其宽度设为0。追加Form级触发器标准在FOLDER_ACTION中追加:app_folder.event(:global.folder_action);在KEY-CLRFRM中追加:app_folder.event(KEY-CLRFRM);追加Form级触发器特殊在WHEN-WINDOW-RESIZED中追加:if :system.event_window in (DEMO_FOLDER) then app_folder.event(WHEN-WINDOW-

23、RESIZED);end if;declarel_x_position number;l_width number;beginif :system.event_window in (DEMO_FOLDER) then app_folder.event(WHEN-WINDOW-RESIZED); l_width:=GET_VIEW_PROPERTY(DEMO_FOLDER_CONTENT,WIDTH); SET_CANVAS_PROPERTY(DEMO_FOLDER_CONTENT,WIDTH,l_width); l_width:=GET_VIEW_PROPERTY(DEMO_FOLDER_ST

24、ACK,WIDTH); l_x_position:=GET_VIEW_PROPERTY(DEMO_FOLDER_STACK,VIEWPORT_X_POS); l_x_position:=l_x_position + l_width + ; SET_BLOCK_PROPERTY(DEMO_FOLDER,BLOCKSCROLLBAR_X_POS,l_x_position); end if;end;注意必须用代码对内容画布进行调整,因为改变窗口大小时,Form不会自动调整。在WHEN-NEW-FORM-INSTANCE中追加:app_folder.define_folder_block(object

25、_name = DEMO_FOLDER, folder_block_name = DEMO_FOLDER, prompt_block_name = DEMO_PROMPT, folder_canvas_name = DEMO_FOLDER_STACK, folder_window_name = DEMO_FOLDER, disabled_functions = , tab_canvas_name = , fixed_canvas_name = );app_folder.event(INSTANTIATE);show_view(DEMO_FOLDER_CONTENT);第一句是Folder申明,

26、根据参数名给出具体值即可,注意tab_canvas_name,我们不用Tab页,所以为空。最后一句是因为本例中内容画布上没有可导航的块,所以需要用带码使其显示。上传&编译&运行运行结果如下:可以调整列宽度和顺序、隐藏或显示列,并可以保存布局;调整窗口大小,Folder会自动调整适应。代码请见。注,上述触发器代码可以全部组织到一个Program Units中。Folder问题Item隐藏后显示,变成可更新蔡芳钧将一个Folder ItemTEXT_ITEM_DISPALYONLY隐藏后然后再显示,这个Item就变成了可以更新的字段了。这个问题的原因是继承过来的STANDARD_FOLDER Ob

27、ject是旧版本导致的,所以如果大家在做Folder Form的时候,检查一下这个问题,如果发现出现以上问题可以删掉Object然后再从效劳器下载一个最新的下来继承。Item隐藏后显示,变成不可更新蔡芳钧当一个Folder ItemTEXT_ITEM隐藏后再显示,这个Item就变成不可更新了,这个问题是由于APPFLDR中代码的问题,当隐藏的时候,它对这个Item执行了set_item_property(prompt_id, DISPLAYED, PROPERTY_OFF)执行这个代码的时候,Form中的帮助说明里有解释,DISPLAYED设为OFF的时候相应也会把UPDATEABLE的属性设

28、为OFF,而执行显示后,set_item_property(prompt_id, DISPLAYED,PROPERTY_ON)并不会相应的把这个Item设为可更新,所以Item就变灰了。要解决这个问题可以在WHEN-NEW-RECORD-INSTANCE中写下相应对Item控制的方法但是如果是多行可能需要点到相应的行上才会将该行的Item显示为可更新,否那么都是灰的,也可以在Form级的触发器FOLDER_RETURN_ACTION中对Item进行逻辑控制,这样就不会出现上面的情况了。Folder开发步骤基于模版这里的模版指汉得提供的,文档由赖旭华提供。基于模版新建Form用Form Buil

29、der翻开TEMPLATE_FOLDER.fmb,把名称改为一个有意义的名称,并另存为相同名称的fmb文件。关闭TEMPLATE_FOLDER.fmb,然后再翻开刚刚保存的文件进行修改。如下列图:创立数据块右键Folder数据块,运行数据块向导,来创立一个数据块,取一个有意义的名字,如ITEM_RELATION。如下列图:创立标题块将FOLDER_PROMPT数据块改成一个有意义的名字,如ITMRE_PROMPT,并把FOLDER_PROMPT数据块中的FIELD1项删除。如下列图:创立标题块把ITEM_RELATION中需要显示的项设置为在堆叠画布FOLDER_STK中显示,并清空属性面板里

30、的“提示属性,然后把物理属性中的X轴坐标和Y轴坐标分别设为0和0.25。项的子类属性按实际需要选择即可创立标题块把上一步设置的项复制到ITMRE_PROMPT数据块中按住Ctrl拖动,然后选复制,并把这些项的子类信息设置为FOLDER_PROMPT_MULTIROW,物理属性中的X轴坐标和Y轴坐标分别设为0和0,然后分别给它们一个有意义的初始值。这些项的宽度属性决定了在上一步设置的项的显示宽度,所以调节显示宽度需要在这个块的项里调。如下列图:更改触发器翻开WHEN-NEW-FORM-INSTANCE触发器,加上如下语句:app_folder.define_folder_block(PTSITM

31、RE, ITEM_RELATION, ITMRE_PROMPT, FOLDER_STK, MAIN);app_folder.event(INSTANTIATE); 其中中的参数含义依次为:Form名,数据块名,PROMPT数据块名,堆叠画布名,主窗口名。 六个步骤做下来之后,Folder就完成了。注意:Folder显示的项不需要手动去画布里调整布局,运行的时候会自动排列开来。横向滚动条会自动产生。JTF Grid开发步骤本节标题说明:标准指做JTF Grid都要做而且是一样的步骤,可以考虑做个模版了;普通指和做普通Form一样;特殊指做JTF Grid都要做但需要根据实际内容作修改。什么是JT

32、F GridJTF Grid不是Form的标准功能,而是Oracle自己在EBS开发中总结出来的“可配置块字段:块中有多少字段可以通过专门的界面定义。对于开发来说,要做的事情就是用“遵循JTF Grid标准换取“增删字段无需修改Form代码。拷贝标准JTF Grid对象标准对象组翻开JTF,把对象组“JTF_GRID拖到我们自己的Form中,并选择“Subclass而非“Copy,这个和前面讲的Folder一样。这样会自动产生一系列用于JTF_GRID的对象:块、画布、参数、Property Classes、Window,尤其注意Form级触发器JTF_GRID_EVENT。这些都不用修改。过

33、程从JTFSTAND.fmb拷贝JTF_CUSTOM_GRID_EVENT过程到我们自己的Form中,然后补上事件处理,暂时全部放null:PROCEDURE jtf_custom_grid_event(gridname IN VARCHAR2, eventtype IN VARCHAR2) ISBEGIN IF eventtype = jtf_grid_events.hyperlink_event THEN NULL; ELSIF eventtype = jtf_grid_events.new_record_event THEN NULL; ELSIF eventtype = jtf_gri

34、d_events.popup_event THEN NULL; ELSIF eventtype = jtf_grid_events.row_selection_event THEN NULL; ELSIF eventtype = jtf_grid_events.end_of_find_event THEN NULL; ELSIF eventtype = jtf_grid_events.doubleclick_event THEN NULL; END IF;END;引用JTF Grid的PLL库标准选中Attached Libraries,点击“+,选择JTF_GRID.pll,其将自动引用JT

35、F_UTIL、JTFDEBUG。如果本地没有请先从效劳器下载。创立数据库对象普通创立数据库对象,没有任何特殊之处,可以使用现成的View和Table,本例子使用gl_je_headers_v。做之前,请确保有总账凭证,不然没有数据;或者你也可以随便换个有数据的视图,但下面的电子表格定义、触发器代码要注意跟着换。定义CRM电子表格特殊N: CRM Adminstrator/Spreadtable/Metadata Administraion输入电子表格名称、源视图、字段定义:创立Grid块普通手工创立非数据库块,标准起见,块名后加“GRID,这里是“DEMO_GRID。当然了,从Template

36、开始的常规修改步骤也是要做的。修改Grid块特殊手工创立非数据库项,并设置这些字段的关键属性:字段名Subclass说明READONLY_GRIDJTF_GRID_ITEM必须,名字随便FINDBUTTON可选DETAILBUTTON可选布局Item到画布普通把DEMO_GRID布局到画布,什么画布都可以,我们需要设置其在画布的启示位置、高度、宽度,因为设计时在画布上不容易看到,我们可以直接设置属性。追加Form级触发器特殊在WHEN-NEW-FORM-INSTANCE中追加:IF NOT jtf_grid.getbooleanproperty(DEMO_GRID.READONLY_GRID,

37、 jtf_grid_property.initialized) THEN jtf_grid.init(jtf_custom.grid_name, GL_JE_HEADERS_V); jtf_grid.setbooleanproperty(DEMO_GRID.READONLY_GRID, jtf_grid_property.allow_multiple_row_selection, FALSE);END IF;编写Find Button触发器特殊用户点击Find,通常是弹出查询界面,输入完条件再执行查询。我们这里省去查询条件界面,直接在FIND按钮的WHEN-BUTTON-PRESSED中编写:

38、jtf_grid.removeallbindvariables(DEMO_GRID.READONLY_GRID);-jtf_grid.setbindvariable(DEMO_GRID.READONLY_GRID, CURRENCY_CODE, CNY);operty(DEMO_GRID.READONLY_GRID, jtf_grid_property.where_clause, CURRENCY_CODE=CNY);IF jtf_grid.getbooleanproperty(DEMO_GRID.READONLY_GRID, jtf_grid_property.is_populated) T

39、HEN jtf_grid.refresh(DEMO_GRID.READONLY_GRID);ELSE jtf_grid.populate(DEMO_GRID.READONLY_GRID);END IF;处理选择事件特殊用户选中某行后,我们可以根据其选中的信息去翻开一个普通块,这样首先需要在FIND按钮的WHEN-BUTTON-PRESSED中编写:jtf_grid.RequestRowSelection(DEMO_GRID.READONLY_GRID);可以翻开该包查看其具体作用。然后在过程jtf_custom_grid_event中响应选择事件:PROCEDURE jtf_custom_gr

40、id_event(gridname IN VARCHAR2, eventtype IN VARCHAR2) IS grid_selection JTF_GRID_PROPERTY.ROW_SELECTION_TYPE; l_startRow number;BEGIN IF eventtype = jtf_grid_events.hyperlink_event THEN NULL; ELSIF eventtype = jtf_grid_events.new_record_event THEN NULL; ELSIF eventtype = jtf_grid_events.popup_event

41、THEN NULL; ELSIF eventtype = jtf_grid_events.row_selection_event THEN grid_selection := jtf_grid.GetRowSelection(DEMO_GRID.READONLY_GRID); if grid_selection.COUNT 0 then l_startRow := grid_selection(1).startRow; fnd_message.debug(jtf_grid.GetColumnCharValue(DEMO_GRID.READONLY_GRID, l_startRow, NAME)

42、; -Do any thing here END IF; ELSIF eventtype = jtf_grid_events.end_of_find_event THEN NULL; ELSIF eventtype = jtf_grid_events.doubleclick_event THENnull; END IF;END;问题:如何响应双击事件呢?上传&编译&运行运行结果如下:代码请见。注,上述触发器代码通常全部组织到一个名字为“JTF_CUSTOM的Program Units中,这样就可以定义一个变量GRID_NAME来保存字段名,免得每处代码重复写DEMO_GRID.READONLY

43、_GRID。如果要使Window变化时Grid跟着变,那么需要参考Folder的做法,在WHEN-WINDOW-RESIZED触发器中调整画布大小、Grid的大小。多语言开发国际化支持说明EBS的国际化支持,也叫多语言支持,包含多个层面:数据库级别:字符集支持多国语言,如UTF8支持全球所有语言数据级别:采用_B表+_TL表+ENV(LANG)环境变量+_VL表+“小地球来实现消息级别:所有消息,通过分语种维护的消息字典获取文件级别:采用分语种目录的形式来实现Forms、Reports的国际化支持Form自身的多语言版本EBS时运行时“找fmx文件,实际上是根据用户登录时选择的语言,首先到$_

44、TOP/forms/下找fmx文件,如果没有那么继续在$_TOP/forms/US下找。也就是说,需要我们维护不同语言的Form编译到不同的目录。不过Oracle提供了工具“Oracle Translation Builder (OTB),可以将多个语言的字符串保存入1个fmb文件,这样在设计时根据NLS_LANG 自动显示该语言的内容,编译时、运行时也是同样道理。更多多语言方面的转换,请参考“Customer Translations。数据多语言开发步骤要求熟练掌握基于Template、基于View的开发过程;要求熟悉EBS中“小地球的操作。下面结合例子直接说明开发步骤和注意点,假定只有2个

45、字段,1个需要维护多语言信息,不考虑弹性域字段。数据库对象的要求:基表B没有什么特殊之处:create table SCF.CUX_MULTILINGUAL_DEMO_B( MULTILINGUAL_DEMO_ID NUMBER not null, MULTILINGUAL_DEMO_CODE VARCHAR2(30) not null, CREATED_BY NUMBER(15) not null, CREATION_DATE DATE not null, LAST_UPDATED_BY NUMBER(15) not null, LAST_UPDATE_DATE DATE not null,

46、 LAST_UPDATE_LOGIN NUMBER(15);create unique index SCF.CUX_MULTILINGUAL_DEMO_B_U1 on SCF.CUX_MULTILINGUAL_DEMO_B (MULTILINGUAL_DEMO_ID);Create Sequence SCF.CUX_MULTILINGUAL_DEMO_B_S;Create Synonym CUX_MULTILINGUAL_DEMO_B For scf.CUX_MULTILINGUAL_DEMO_B;Create Synonym CUX_MULTILINGUAL_DEMO_B_S For scf

47、.CUX_MULTILINGUAL_DEMO_B_S;数据库对象的要求:多语言表TL主键字段:基表主键+LANGUAGE。其他字段:需要维护多语言的字段+Who字段+SOURCE_LANG。create table SCF.CUX_MULTILINGUAL_DEMO_TL( MULTILINGUAL_DEMO_ID NUMBER not null, DESCRIPTION VARCHAR2(255), LANGUAGE VARCHAR2(4) not null, CREATED_BY NUMBER(15) not null, CREATION_DATE DATE not null, LAST_

48、UPDATED_BY NUMBER(15) not null, LAST_UPDATE_DATE DATE not null, LAST_UPDATE_LOGIN NUMBER(15), SOURCE_LANG VARCHAR2(4) not null);create unique index SCF.CUX_MULTILINGUAL_DEMO_TL_U1 on SCF.CUX_MULTILINGUAL_DEMO_TL(MULTILINGUAL_DEMO_ID, LANGUAGE);Create Synonym CUX_MULTILINGUAL_DEMO_TL For scf.CUX_MULT

49、ILINGUAL_DEMO_TL;数据库对象的要求:视图VL该视图根据登录用户的语言过滤数据:Create Or Replace View CUX_MULTILINGUAL_DEMO_VL AsSELECT b.ROWID row_id, b.multilingual_demo_id, b.multilingual_demo_code, t.descriptioned_by, b.last_update_date, b.last_update_login FROM scf.cux_multilingual_demo_b b, scf.cux_multilingual_demo_tl t WHE

50、RE b.multilingual_demo_id = t.multilingual_demo_id AND t.LANGUAGE = userenv(LANG);数据库对象的要求:表操作API需要同时操作TL表,同时提供add_language过程,供EBS启用新语言时使用。以下代码仅关注“-Process TL table here局部即可:CREATE OR REPLACE PACKAGE cux_multilingual_demo_pkg AUTHID CURRENT_USER AS /*= * PROCEDURE: insert_row() *=*/ PROCEDURE insert

51、_row(x_row_id IN OUT VARCHAR2, x_multilingual_demo_id IN OUT NUMBER, p_multilingual_demo_code IN VARCHAR2, p_description IN VARCHAR2, p_creation_date IN DATE, p_created_by IN NUMBER, p_last_update_date IN DATE, p_last_updated_by IN NUMBER, p_last_update_login IN NUMBER); /*= * PROCEDURE: lock_row()

52、*=*/ PROCEDURE lock_row(p_multilingual_demo_id IN NUMBER, p_multilingual_demo_code IN VARCHAR2, p_description IN VARCHAR2 DEFAULT NULL); /*= * PROCEDURE: update_row() *=*/ PROCEDURE update_row(p_multilingual_demo_id IN NUMBER, p_multilingual_demo_code IN VARCHAR2, p_description IN VARCHAR2, p_last_u

53、pdate_date IN DATE, p_last_updated_by IN NUMBER, p_last_update_login IN NUMBER); /*= * PROCEDURE: delete_row() *=*/ PROCEDURE delete_row(p_multilingual_demo_id IN NUMBER); /*= * PROCEDURE: add_language() *=*/ PROCEDURE add_language;END cux_multilingual_demo_pkg;/CREATE OR REPLACE PACKAGE BODY cux_mu

54、ltilingual_demo_pkg AS /*= * PROCEDURE: insert_row() *=*/ PROCEDURE insert_row(x_row_id IN OUT VARCHAR2, x_multilingual_demo_id IN OUT NUMBER, p_multilingual_demo_code IN VARCHAR2, p_description IN VARCHAR2, p_creation_date IN DATE, p_created_by IN NUMBER, p_last_update_date IN DATE, p_last_updated_

55、by IN NUMBER, p_last_update_login IN NUMBER) IS CURSOR c IS SELECT ROWID FROM cux_multilingual_demo_b WHERE multilingual_demo_id = x_multilingual_demo_id; BEGIN IF x_multilingual_demo_id IS NULL THEN SELECT cux_multilingual_demo_b_s.NEXTVAL INTO x_multilingual_demo_id FROM dual; END IF; INSERT INTO

56、cux_multilingual_demo_b (multilingual_demo_id, multilingual_demo_code, created_by, creation_date, last_updated_by, last_update_date, last_update_login) VALUES (x_multilingual_demo_id, p_multilingual_demo_code, p_created_by, p_creation_date, p_last_updated_by, p_last_update_date, p_last_update_login)

57、; -Process TL table here INSERT INTO cux_multilingual_demo_tl (multilingual_demo_id, description, created_by, creation_date, last_updated_by, last_update_date, last_update_login, LANGUAGE, source_lang) SELECT x_multilingual_demo_id, p_description, p_created_by, p_creation_date, p_last_updated_by, p_

58、last_update_date, p_last_update_login, l.language_code, userenv(LANG) FROM fnd_languages l WHERE l.installed_flag IN (I, B) AND NOT EXISTS (SELECT NULL FROM cux_multilingual_demo_tl t WHERE t.multilingual_demo_id = x_multilingual_demo_id AND t.LANGUAGE = l.language_code); OPEN c; FETCH c INTO x_row_

59、id; IF (c%NOTFOUND) THEN CLOSE c; RAISE no_data_found; END IF; CLOSE c; END insert_row; /*= * PROCEDURE: lock_row() *=*/ PROCEDURE lock_row(p_multilingual_demo_id IN NUMBER, p_multilingual_demo_code IN VARCHAR2, p_description IN VARCHAR2 DEFAULT NULL) IS CURSOR c IS SELECT multilingual_demo_id, mult

60、ilingual_demo_code FROM cux_multilingual_demo_b WHERE multilingual_demo_id = p_multilingual_demo_id FOR UPDATE OF multilingual_demo_id NOWAIT; rec c%ROWTYPE; -Process TL table here CURSOR c1 IS SELECT description FROM cux_multilingual_demo_tl WHERE multilingual_demo_id = p_multilingual_demo_id AND L

61、ANGUAGE = userenv(LANG) FOR UPDATE OF multilingual_demo_id NOWAIT; tlrec c1%ROWTYPE; BEGIN OPEN c; FETCH c INTO rec; IF (c%NOTFOUND) THEN CLOSE c; fnd_message.set_name(FND, FORM_RECORD_DELETED); app_exception.raise_exception; END IF; CLOSE c; IF (rec.multilingual_demo_id = p_multilingual_demo_id) AN

62、D (rec.multilingual_demo_code = p_multilingual_demo_code) OR (rec.multilingual_demo_code IS NULL) AND (p_multilingual_demo_code IS NULL) THEN NULL; ELSE fnd_message.set_name(FND, FORM_RECORD_CHANGED); app_exception.raise_exception; END IF; -Process TL table here OPEN c1; FETCH c1 INTO tlrec; IF (c1%

63、NOTFOUND) THEN CLOSE c1; fnd_message.set_name(FND, FORM_RECORD_DELETED); app_exception.raise_exception; END IF; CLOSE c1; IF (tlrec.description = p_description) OR (tlrec.description IS NULL) AND (p_description IS NULL) THEN NULL; ELSE fnd_message.set_name(FND, FORM_RECORD_CHANGED); app_exception.ra

64、ise_exception; END IF; END lock_row; /*= * PROCEDURE: update_row() *=*/ PROCEDURE update_row(p_multilingual_demo_id IN NUMBER, p_multilingual_demo_code IN VARCHAR2, p_description IN VARCHAR2, p_last_update_date IN DATE, p_last_updated_by IN NUMBER, p_last_update_login IN NUMBER) IS BEGIN UPDATE cux_

65、multilingual_demo_b SET multilingual_demo_id = p_multilingual_demo_id, multilingual_demo_code = p_multilingual_demo_code, last_update_date = p_last_update_date, last_updated_by = p_last_updated_by, last_update_login = p_last_update_login WHERE multilingual_demo_id = p_multilingual_demo_id; IF (SQL%N

66、OTFOUND) THEN RAISE no_data_found; END IF; -Process TL table here UPDATE cux_multilingual_demo_tl SET description = p_description, source_lang = userenv(LANG), last_update_date = p_last_update_date, last_updated_by = p_last_updated_by, last_update_login = p_last_update_login WHERE multilingual_demo_id = p_multilingual_demo_id AND userenv(LANG) IN (LANGUAGE, source_lang); IF (SQL%NOTFOUND) THEN RAISE no_data_found; END IF; END update_row; /*= * PROCEDURE: delete_row() *=*/ PROCEDURE delete_row(p_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论