zoukankan      html  css  js  c++  java
  • 转:ORACLEERP开发基础之EBS开发基础

    转自:http://blog.itpub.net/8781091/viewspace-1012244/

    【内容导航】

    [@more@]

    文本Tag: Oracle ERP

      【IT168 技术文档】ORACLEERP开发基础之前言

      http://tech.it168.com/a2009/0427/274/000000274048.shtml

      ORACLE ERP开发之OracleForms基础(一)Forms设置部分

      http://tech.it168.com/a2009/0428/274/000000274178.shtml

      ORACLEERP开发基础之OracleForms基础(二)FORMS代码部份

      http://tech.it168.com/a2009/0428/274/000000274236.shtml

      ORACLE ERP开发基础之Oracle Report基础

      http://tech.it168.com/a2009/0429/274/000000274343.shtml
         ORACLEERP开发基础之Oracle数据库基础 http://tech.it168.com/a2009/0504/274/000000274773.shtml      开发工具安装

      Oracle EBS11i 开发工具是developer6i的东西,非常古老。因为是转手过来的机器,开发工具都是安装好了,

      所以也没去在意这工具的安装。今天系统重装了,才知道这工具安装起来也是特烦人的。

      先安装FORMS6i与REPORT6i,安装完后一定要打补丁。否则会出现一大堆莫名的错误。接着安装discoverer。

      安装discoverer时先将注册表备份出来,因为discoverer不能和Forms安装在同一目录。然后再安装 discoverer的补

      丁,接着再将注册表恢复回来。

      大致这样可以了。注意顺序一定要不能错了,否则又会出现一堆无聊的错误。唉!developer6i是98年的工

      具。盼着EBS R12应该是用DEVELOPER10g吧。

      EBS二次开发包注册

      2.1 从 Server 中下载 ERP Library (.pll), 存放于本机Server Path : /u01/au/11.5.0/resource

      Form文件与Library文件要存放在固定目录

      例如: Form存放在 d:ErpFormForm

      Library 存放在d:ErpFormLibrary;

      2.2 在 Regedit > HKEY_LOCAL_MACHINE > SOFTWARE > ORACLE > FORMS60_PATH

      加入client 端存放 Form 及 Library的路径(如图)

      

      例如:d:ErpFormLibrary;d:ErpFormForm(建议要加在最前面)

      利用TEMPLATE.fmb 模板来开发Form

      Oracle 已经为我们提供了一个Form 的开发模板,(/data/deve/devappl/au/11.5.0/forms/ZHS/TEMPLATE.fmb)

      我们的开发实际要基于这个模板,这个模板里面已经存在了我们将会用到的Oracle 标准的对象,我们需要做的,

      就是这这个模板的基础上面,添加我们自己的对象。这也是人家说二次开发没啥技术含量的重大原因。但如果

      真让你出写那么PL 包,估计也没几人能写好。人有时就是这样,让你站在巨人的肩膀,还在抱怨这抱怨那的。

      我也是这类人啦。出出气呀。^_^!

      1、更改template.fmb 文件名,同时删除一些无用的样本对象。

      2、增加数据块

      

      一路照做就可以了,步骤太简单就不用讲了吧。完成后,选择“仅创建数据块”。

      3、增加一个画布

      选择工具菜单上面的布局向导来做。

      

      注意:选择画布时,选择新画布。如上图。

      

      显示记录数一般为10就可以了。如上图。

      注:将画布名称改成与数据块的名称一致

      4、增加一个窗口

      

      注:窗口尽量保持与画面一致,同时选择相应的主画布。对应的画布那边也要选择主窗口

      5、选择对象的子类信息

      

      所有的对象都应选择相对的子类信息,这边仅以BLOCK为例。

      6、调整布局 不需要显示到画布的ITEM,可以将ITEM的画布属性设成空

      

      7、修改触发器(这一步很关键!)

      

      8、选择第一导航块

      

      9、上传及编译FORMS

      9.1先将FORMS上传至/data/deve/devappl/au/11.5.0/forms/ZHS/

      9.2telnet至server,进入/data/deve/devappl/au/11.5.0/forms/ZHS/目录

      目录:cd /data/deve/devappl/au/11.5.0/forms/ZHS/ 编译:f60gen FRMSTONE.fmb apps/apps 复制:cp FRMSTONE.fmx /data/deve/deveappl/hek/11.5.0/forms/ZHS/ 注:一定要进入FORM的目录,再进行编译。否则编译也可以通过,但会出现奇怪的问题。这个问题折腾了我二天时间,才发现是ORACLE的BUG。 好了,一个最基本的EBS FORM就开发完成了。

      注册表单FORM

      1.定义表单

      操作路径:应用开发员=>应用产品=>表单

      

      填写说明如下:

      表单:FORMS文件名

      应用:HEK 惠尔康客户化应用

      用户表单名:这个参数与“功能”中的表单名是相关联的。

      2.定义功能 操作路径:应用开发员=>应用产品=>功能

      2.1

      

      2.2

      

      2.3

      

      3.定义菜单

      操作路径:应用开发员=>应用产品=>菜单

      

      注:“子菜单”是指菜单可以将另一个菜单的功能全部包含进来。也就是父菜单的关系。

      5. 完成设置,效果如下:

      

      注册请求

      1.定义可执行

      路径:系统管理员->并发->方案->可执行

      

      注意:定义成请求的过程或函数,必须加入(Errbuf Out Varchar2,Retcode Out Number)两个形参。

      2.定义并发程序

      路径:系统管理员->并发->方案->可执行

      注意:并发程序界面的可执行组中的“名称”,与上面的可执行并发程序界面的“简称”是一致的。

      

      注意:如果要传入参数到PL/SQL包中,点击《参数》按钮进行设置。

      

      也可以为参数赋给默认值,例:默认取得用户ID

      

      如果要限定参数的取数范围,则要定义值集(如何定义?请参考后面的定义值集)。

      3.定义请求组 路径:系统管理员->安全性->责任->请求

      

      4.将请求组置于职责下

      系统管理员->安全性->责任->定义

      注册职责

      1.新建菜单 操作路径:应用开发员=>应用产品=>应用菜单

      

      2.新建一个职责

      操作路径:系统管理员=>安全性=>责任=>定义

      

      将职责分配给用户

      操作路径:系统管理员=>安全性=>用户=>定义

      

      3.转到EBS主页,多显示一个职责。

      

      注册值集

      1.定义集 操作路径:总帐=>设置=>财务系统=>验证=>集

      

      1.1如果值的来源于数据表,则值的验证类型选择“表”,然后点击“编辑信息”。

      

      注:如果要实现请求参数的值集来源,作前后过滤条件的话。其语法:

      where head.customer_number = :$FLEX$.HEK_OM_KHJGB_ACCT_CUST

      and head.created_by = :$FLEX$.HEK_OM_FHD_CREATE_BY

      and TO_CHAR(head.ordered_date,'YYYYMMDD') = :$FLEX$.HEK_DAY_TIME_ID ORDER BY HEAD.ORDER_NUMBER

      :$FLEX$.为参数界面的名称

      HEK_OM_KHJGB_ACCT_CUST为某个参数的值集名称。

      1.2实现的效果如下:

      

      1.3定义多列值集

      

      1.4实现效果

      

      1.5从属

      2.定义值

      2.1如果值的来源固定的某些值,那么可以直接定义值。将值的验证类型选择=>独立

      

      2.2定义集所对应的值

      操作路径:操作路径:总帐=>设置=>财务系统=>验证=>值

      

      通过应用开发员取得系统管理员责任

      一般公司都有区分DBA与DEVELOPER的,业务机上一般是APPS用户由DBA掌握,诸如用户管理也是DBA来负责的。developer是不知道 没有APPS密码,也没有‖SYSTEM ADMINISTTRATOR―职责的。也就是说DEVELOPER只有‖Application Developer―这个职责。同理,应用开发员是没有权限给终端用户加权限的。 但我今天测试了一下,developer虽然没直接加职责的权限,但developer有‖Application Developer―职责,这个职责下面有注册菜单的权限,完全可以通过注册菜单将SYSTEM ADMINISTROR加进来。如图:

      

      查询视图时没有显示数据

      在EBS以外的地方(含report),如果确认SQL语句没有问题,这主要是因为视图是OU屏蔽的,因此需要初始化身份。例如:PO_HEADERS。有两种方法,方法一适用于知道相应的组织代码,方法二就比较通用了。

      方法一:

      BEGIN

      DBMS_APPLICATION_INFO.set_client_info(122); --122代表具体的组织代码,不同公司,代码是不同。

      END;

      方法二:

      BEGIN

      APPS.FND_GLOBAL.apps_initialize

      ( user_id =>APPS.FND_GLOBAL.user_id, resp_id =>APPS.FND_GLOBAL.resp_id, resp_appl_id =>APPS.FND_GLOBAL.resp_appl_id );

      END;

      注册报表(report)

      路径:系统管理员->并发->方案->可执行

      注册报表与注册请求的步骤是差不多的。

      

      定义并发

      路径:系统管理员->并发->方案->定义

      

      定义报表参数

      点击上图的参数按钮。

      

      注:这边与注册请求不一样的就是,要填写变量栏(变量名称就是REPORT中的变量名称)

      定义请求组

      操作路径:系统管理员->安全性->责任->请求

      

      将请求组置于职责下

      系统管理员->安全性->责任->定义

      

      OK,完成了报表的注册。

      请求的输出及日志

      1、Effect:

      

      Oracle EBS会在EBS的安装目录,保存查看输出及日志之文件。查看具体目录:

      select t.logfile_name,t.outfile_name from fnd_concurrent_requests t

      where t.request_id = _request_id

      2、当我们自行定义了一个并发请求时,也经常需要使用上面的方式进行一些调试。

      请求的输出:apps.Fnd_File.Put_line (apps.FND_FILE.OUTPUT, '请求的输出');

      请求的日志:apps.Fnd_File.Put_line (apps.FND_FILE.LOG, '请求的日志');

      对于报表,一般情况是把报表的内容输出到OUTPUT,把报表中间的debug逻辑输出到日志中。

      对于请求包,一般情况是输出到日志中。OUTPUT就不用管了。

      实现手动提交请求

      在Form里面,我们可以用

      APPS.FND_REQUEST.SUBMIT_REQUEST

      提交一个Request到Oracle Request Manager。如果提交成功,该函数返回Request ID,否则,返回0。

      1、初始化

      在提交一个Request之前,我们会调用Oracle Standard的Procedure对这个Request做一些基本的参数的初始化。

      APPS.FND_GLOBAL.apps_initialize

      ( user_id =>APPS.FND_GLOBAL.user_id, resp_id =>APPS.FND_GLOBAL.resp_id, resp_appl_id =>APPS.FND_GLOBAL.resp_appl_id );

      注:这个初始化不是必须的,之所以要初始化,是因为视图是OU屏蔽的。 上述语句等同于dbms_application_info.set_client_info;

      2、函数介绍

      2.1 函数APPS.FND_REQUEST.SUBMIT_REQUEST有105个参数:

      APPS.FND_REQUEST.SUBMIT_REQUEST

      ( APPLICATION IN VARCHAR2 DEFAULT NULL,

      PROGRAM IN VARCHAR2 DEFAULT NULL,

      DESCRIPTION IN VARCHAR2 DEFAULT NULL,

      START_TIME IN VARCHAR2 DEFAULT NULL,

      SUB_REQUEST IN BOOLEAN DEFAULT FALSE,

      chr(0),'','','','','','','','','','','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','', '','','','','','','','','','' )

      RETURN NUMBER;

      2.2 参数详解

      2.2.1 APPLICATION(必需参数)

      应用程序的名称缩写。一般我们可能会用到下面的几个:

      Oracle Assets „„> OFA

      Oracle General Ledger „„> SQLGL

      Oracle Inventory „„>INV

      Oracle Order Management „„>ONT

      Oracle Payables „„SQLAP

      Oracle Pricing „„QP

      Oracle Purchasing „„PO

      Oracle Receivables „„AR

      操作路径:系统管理员=>应用=>注册

      

      2.2.2 PROGRAM(必需参数)

      要提交到Oracle Request Manager的并发程序之简称

      操作路径:应用开发员=>并发=>程序

      

      2.2.3 第三、第四个参数

      第三、第四个参数默认为空

      2.2.4 第五个参数

      第五个参数默认为false

      2.2.5 第六至第十零五个参数

      第六至第十零五个参数为要传入到请求中的自定义参数值。如果无须这么多参数时,以chr(0)作为参数结束的标记。Chr(0)后面剩余的参数为 ‘‘。

      手动提交请求示例

      declare

      v_order_number number;

      v_req_id number;

      begin

      v_order_number := :HEK_ODS_TH_FEE_M_V.OE_HEAD_NUMBER;

      if :HEK_ODS_TH_FEE_M_V.OE_HEAD_NUMBER is null then FND_MESSAGE.DEBUG('请选择配送单后再打印!');

      RAISE FORM_TRIGGER_FAILURE;

      end if;

      v_req_id := fnd_request.submit_request('HEK',

      'HEK_退货单',

      '', '',

      FALSE, v_order_number,--v_batch_no, null,--v_batch_no, null,--v_cust_num, null,--v_driver_num, null,--v_trans_num, null,--v_vendor_num, null, null,null, chr(0), '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '','', '', '', '', '', '', '', '', '', '','', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '','');

      if (v_req_id = 0) then FND_MESSAGE.RETRIEVE;

      FND_MESSAGE.ERROR;

      else

      update HEK_ODS_TH_FEE_M set print_mark='Y' where OE_HEAD_NUMBER = (v_order_number);

      commit_form;

      fnd_message.debug('您的请求已经提交,请求号为:' || to_char(v_req_id) || ',请通过查看->请求来查看输出结果。');

      end if;

      end;

      客制化菜单

      Effect:

      

      Usage:调用 app_special.instantiate包

      Examples:

      1、增加一个自定义Form Level的触发器(SPECIAL11)

      

      2、增加测试代码如下:

      ――――――――――――――――――――――――――――――――――――――――――――――

      declare

      v_invoice_num varchar2(50);

      begin

      v_invoice_num := '菜单栏客制化100';

      fnd_message.debug(v_invoice_num);

      end;

      ―――――――――――――――――――――――――――――――――――――――――――――――

      3、在Form WHEN-NEW-FORM-INSTANCEFJ 进行调用:

      APP_SPECIAL.INSTANTIATE('SPECIAL11','测试菜单2', '', TRUE, 'LINE');

      ―――――――――――――――――――――――――――――――――――――――――――――――

      4、一些特殊说明:

      上面自定义FORMS级触发器,名字必须定义为“SPECIAL+数字‖,否则会报错。并且数字的大小决定了菜单出现的先后顺序。数字还有更大作用就是决定了,自定义菜单选项放在哪个主菜单下。

      SPECIAL1—SPECIAL15在“工具”主菜单下。

      SPECIAL16—SPECIAL30在“报表”主菜单下。

      SPECIAL31—SPECIAL45在“活动”主菜单下。

      SPECIAL46以上就直接报错了。^_^

      如下图

      

      5、 控制自定义菜单的是否激活可用。

      使用app_special.enable函数可以控制菜单是否可以使用。

      例如:基于不同的数据块,实现菜单的不可用。在block的‖when-new-block-instance‖中加入

      效果:

      app_special.enable('SPECIAL1',property_off);

      效果

      

      6、 在自定义的菜单上使用checkbox按钮。

      ①增加一个自定义Form Level的触发器(SPECIAL1_CHECKBOX),代码如下:

      if app_special.get_checkbox('SPECIAL1_CHECKBOX')='TRUE' then

      fnd_message.debug('Special 1 is True!');

      else

      fnd_message.debug('Special 1 is False!');

      end if;

      注:使用app_special.get_checkbox来获取checkbox的状态值。

      ②在Form的WHEN-NEW-FORM-INSTANCE触发器中初始化菜单。

      app_special.instantiate('SPECIAL1_CHECKBOX','Spe&cial 1 Box w Line', '',TRUE,'LINE');

      app_special.set_checkbox('SPECIAL1_CHECKBOX','TRUE');

      注:app_special.set_checkbox是对checkbox进行赋值操作。

      ③效果如下:

      

      客制化右键菜单

      1、 首先如果是要为某个ITEM,另外开发一个右键菜单。这个需要直接按照FORM的开发教程,自定义一个POPUP菜单就可以了。但本文讲的在EBS所有的快捷菜单上,额外增加所需的菜单按钮。也就是要图上所示的快捷菜单上增加菜单按钮。

      

      2、 在FROM-LEVEL增加自定义触发器(名字规则为:POPUP+N)

      

      3、 ITEM的“PRE-POPUP-MENU”触发器上初始化菜单。

      APP_POPUP.INSTANTIATE('POPUP1','First Entry');

      APP_POPUP.INSTANTIATE('POPUP10','SECONED Entry',TRUE,'LINE');

      APP_POPUP.INSTANTIATE('POPUP3','THREE Entry',FALSE,NULL);

      

      4、 如果是整个BLOCK的ITEM都需要客制化快捷菜单,可以在BLOCK的“PRE-POPUP-MENU”定义。

      APP_POPUP.INSTANTIATE('POPUP1','global');

      

      调用EBS日期控件

      1、 首先将ITEM的LOV属性设置为“ENABLE_LIST_LAMP”、列表验证属性设置为“否”

      

      2、在ITEM的“KEY-LISTVAL”解发器下加入对下代码:

      BEGIN

      calendar.show();

      END;

      3、注意:ITEM对应数据库类型必须是DATE类型,否则会报frm-40700错误。效果如下:

      

      查询数据时限定语言环境

      EBS是个多语言的业务系统,界面上只查询到一条记录,实际上后台数据表是多条记录的。如:值集表。

      select * from apps.FND_FLEX_VALUES_TL t, apps.FND_FLEX_VALUES B

      where B.FLEX_VALUE_ID = T.FLEX_VALUE_ID

      and t.language = userenv('LANG')

      实现历史记录查询

      1.要实现的效果

      

      2.在定义数据表时,必须加入以下五个字段:

      

      即:CREATED_BY NUMBER、CREATION_DATE DATE、LAST_UPDATED_BY NUMBER、LAST_UPDATE_DATE DATE、LAST_UPDATE_LOGIN NUMBER 网上有些文章说还必须定义主键、序列。但如果仅实现此功能是不需要的。当然从数据库设计方面来说,这些定义也是必须的。

      3、在数据块的PRE-INSERT、PRE-UPDATE触发器中加入代码 FND_STANDARD.SET_WHO;

      实现文件夹功能

      1、在客制的Form里面实现Oracle Folder的功能,最终效果如下:

      

      2、使用TEMPLATE.fmb创建一个Form(名称:FRMSTONE)。

      2.1添加Form Objects 包括一个Window,MY_FOLDER

      一个Canvas, MY_FOLDER 一个Block,MY_FOLDER(可以使用向导创建),并修改其属性。如下图:

      

      注:使用文件夹的数据块,其名称总长不能超过22字节!

      2.2修改Trigger和ProgramUnits

      Form Level Trigger: PRE-FORM:

      app_window.set_window_position('MYFOLDER', 'FIRST_WINDOW');

      Program Units:APP_CUSTOM:

      if (wnd = 'MYFOLDER') then app_window.close_first_window;

      2.3修改FORM属性设置

      

      注:须要说明的是:设成第一个导航数据块的blockname必须至少一个item处于canvas中,否则会报FRM-40106的错误。

      2.4其他的具体步骤同一般的FORM开发一样,就不多说了。

      3、添加Folder相关的Objects

      3.1文件夹相关的Window、Canvas、Block、Item…等都包含在Oracle Standard Form APPSTAND.FMB。

      3.2在同一窗口打开标准的Form和我们自己客制的Form,并且选择APPSTAND.FMB 的Object Groups STANDARD_FOLDER然后用鼠标拖动至我们自己的Form的Object Groups。

      

      3.3此时会弹出对话框:

      

      选择子类,你会发现Form Builder都会在你的Form里面自动添加很多对象。做完这一步后,请不要关闭APPSTAND.FMB。

      4、增加Attached Libraries

      做完上面的步骤后,检查一下Attached libraries里面有没有APPFLDR。如果没有,我们需要手工添加。

      

      5、增加Stacked Canvas FOLDER_STACK 这一步是必须的,而且你期望实现Folder拖动功能的那些Item都是放在这个Canvas里面,这个Stacked Canvas又是放在前面我们建立的Canvas:MY_FOLDER上面的。

      5.1增加Stacked Canvas 双击打开Canvas MY_FOLDER,在左侧工具条里面选择Stacked Canvas,然后在Canvas MY_FOLDER里面拖动即可。

      

      5.2设置Stacked Canvas属性

      

      6、更改数据块MY_FOLDER中的Item属性

      

      7、创建控制块MY_FOLDER_PROMPT

      7.1设置块的属性 子类信息:block 数据库数据块:否

      7.2增加ITEM 注:增加Item,名称必须和Block MY_FOLDER中的Item保持一致。 另外,数据块中有些item(如id)不要显示在canvas上的,那么此类item也无须在MY_FOLDER_PROMPT创建相应的item.

      

      7.2设置其初始值,也就是显示的标签名及子类信息

      

      7.3增加其他相关Item 我们还需要增加其他的一些Item,都是和Folder的功能有关的。

      

      

      8、增加相应的trigger

      

      9、其他注意事项

      9.1错误:在编译带有文件夹的FORM时,经常会出现如下提示。

      FRM-30085: Unable to adjust form for output

      这是因为ITEM超出的了画布的高度或是宽度造成的。如图:

      

      可以通过调整ITEM的X坐标或Y坐标来解决此错误。

      9.2错误:无法实现拖动。

      

      解决:数据块的item与folder的item与调整一定的距离。

      

      实现手电筒查找的功能

      首先,先按TEMPLATE将其他功能先实现,然后再来实现查找的功能。手电筒查找的Effect有两二种,①LOV形式,②window形式。

      1、LOV查找模式:一般适用于查询结果只返回单条条件的查询(如主从数据块的界面)。

      ①创建一个parameter参数:TEST_P

      ②创建一个基于主键查询LOV-TEST_L,并将主键字段映射给Parameter参数TEST_P。

      

      ③在数据块中创建PRE-QUERY触发器。

      IF :parameter.G_query_find = 'TRUE' THEN :BLOCKNAME.HEADER_ID := :parameter.TEST_P; :parameter.G_query_find := 'FALSE';

      end if;

      ④在数据块中再创建QUERY_FIND触发器。

      begin

      app_find.query_find('TEST_L'); --调用LOV

      end;

      ⑤完成效果如下:

      

      2、WINDOW查找模式:一般适用多条件查询,可以返回多条查询记录。

      ①打开在标准FORM---APPSTAND.fmb。将对象组中的QUERY_FIND拖至待开发的FORM中。

      

      ②重命名第一个数据块、画布、窗口(QUERY_***都是刚才自动创建的)。USER GUID说可以重命名,但我没有重命名成功。也懒得去折腾一个命名的问题。^_^ ③打开QUERY_FIND画布,改写“新建”、“查找”两个按钮WHEN-BUTTON-PRESS之中的代码。

      

      NEW按钮代码:

      --app_find.new('Your blockname here'); app_find.new('HEK_SALE_CUST_MANUAL');

      FIND按钮代码:

      :parameter.G_query_find := 'TRUE'; --app_find.find('your blockname here'); app_find.find('HEK_SALE_CUST_MANUAL'); :parameter.G_query_find := 'FALSE';

      ④设置QUERY_FIND数据块的“前一导航数据块”,也就是要实现询查功能的数据块。

      

      ⑤修改QUERY_FIND数据块KEY-NXTBLK触发器代码

      :parameter.G_query_find := 'TRUE'; --app_find.find('your blockname here'); app_find.find('HEK_SALE_CUST_MANUAL'); :parameter.G_query_find := 'FALSE';

      ⑦修改QUERY_FIND窗口的标题及尺寸,并在QUERY_FIND画布上创建要查找的条件ITEM。 ⑧在要实现查询的数据块(如:HEK_SALE_CUST_MANUAL),创建PRE-QUERY触发器。

      

      if :parameter.g_query_find = 'TRUE' then

      app_find.query_range(name_in('query_find.CUSTOMER_NUMBER'),name_in('query_find.CUSTOMER_NUMBER'),'HEK_SALE_CUST_MANUAL.CUST_CODE');

      app_find.query_range(:query_find.CUST_DATE,:query_find.CUST_DATE,'HEK_SALE_CUST_MANUAL.TIME_ID'); :parameter.G_query_find := 'FALSE';

      end if;

      注:app_find.query_range参数前两个是QUERY_FIND中的ITEM,后一个是查询块中的ITEM。

      ⑨在要实现查询的数据块(如:HEK_SALE_CUST_MANUAL),再创建QUERY_FIND触发器。

      --APP_FIND.QUERY_FIND('','',''); app_find.query_find('HEK_SALE_DEPT_MANUAL','QUERY_FIND','QUERY_FIND');

      ⑩完成效果如下:

      

      记录指示器切换标签页

      Effect:

      

      1、 在该数据块中手工增加一个ITEM

      

      设置ITEM的属性:子类信息:设成DRILLDOWN_RECORD_INDICATOR,数据库项:否.

      2.在新增的ITEM的WHEN-MOUSE-CLICK触发器加入

      declare

      v_order number;

      begin

      v_order := : block_name1.item; --block_name表示要切换tab的数据块

      if v_order is not null then

      go_block(' block_name1');

      set_block_property('block_name1 ',DEFAULT_WHERE,'ORDER_NUMBER='||v_order);

      execute_query;

      end if;

      end;

      3.这样就可以实现类似VB中的TAB切换了。由于ORACLE FORM没有专门的TAB函数,只能如此曲折实现。

      EBS的条件查询方法

      1、使用app_find.find

      IF (NAME_IN('PO_HEADERS.PO_HEADER_ID') IS NOT NULL) THEN

      :parameter.G_query_find := 'TRUE';

      app_find.find('CUX_PO_HEADERS_ADD_MESSAGE');

      go_block('CUX_PO_HEADERS_ADD_MESSAGE');

      :parameter.G_query_find := 'FALSE';

      ELSE

      FND_MESSAGE.DEBUG('请先保存订单头');

      END IF;

      在CUX_PO_HEADERS_ADD_MESSAGE的PRE-BLOCK中处理

      copy(name_in('PO_HEADERS.PO_HEADER_ID'),'CUX_PO_HEADERS_ADD_MESSAGE.PO_HEADER_ID');

      2、使用Default_where属性处理

      declare

      lv_default varchar2(2000);

      begin

      lv_default:='.....';

      go_block('CUX_PO_HEADERS_ADD_MESSAGE');

      set_block_property('CUX_PO_HEADERS_ADD_MESSAGE',DEFAULT_WHERE,‘PO_HEADER_ID=‘||lv_default);

      execute_query;

      end;

      3、使用app_find.query_range()来处理 注:app_find.query_range()必须有三个参数,也只能有三个参数

      begin

      app_find.query_range(:find_date_from, :find_date_to, 'CUX_PO_HEADERS_ADD_MESSAGE.REATE_DATE'); :parameter.Q_query_find:='false';

      end;

      4、查询综合运用举例

      前提准备工作,数据块:HKE_TEST 控制块:CONTROL

      4.1.在数据块HKE_TEST的PRE-QUERY触发器设定查询条件

      if :parameter.g_query_find = 'TRUE' then

      app_find.query_range(:CONTROL.CUST_F, :CONTROL.CUST_F ,'HKE_TEST.CUSTOMER_NUMBER'); :parameter.g_query_find := 'FALSE';

      end if;

      4.2在查询按钮的WHEN-BUTTON-PRESSED

      :parameter.G_query_find := 'TRUE';

      app_find.find('HEK_TEST');

      :parameter.G_query_find := 'FALSE';

      自定义代码

      例:实现某个项为必填项(当然自定义代码的功能还有很多)。

      

      菜单:诊断=>自定义代码=>个性化

      

      选择相应的触发器。如果是基于block的触发器,则要选择触发器对象(是哪一个块?)。

      

      选择相应的项为必填。注:项的名称可通“检查”来查看。

      

      作用于项的内容是什么,本例为必填。

      

      保存完后,就可以实现“销售人员这一项为必填了”。

      

      Fnd_Profile

      begin

      fnd_message.debug('user_id= ' || fnd_profile.value('user_id')); --取当前登录EBS用户ID

      fnd_message.debug('user_name= '||fnd_profile.value('USERNAME')); --取当前登录EBS用户名

      fnd_message.debug('FND_Global.User_Name='|| FND_Global.User_Name); --取当前登录EBS用户名 fnd_message.set_string('GL_SET_OF_BKS_ID='||fnd_profile.value('GL_SET_OF_BKS_ID'));

      fnd_message.show; --取当前帐套

      end;

      弹性域

      弹性域分成键弹性域、说明性弹性域。这两种弹性域用途是不一样的。 关键性弹性域:在使用KEY弹性域的基表中,只保存ID。但可以通ID查询到相应的SEGMENT。在表结构中表现为***_ID、SEGMENT1等。 说明性弹性域:针对特定用户扩展输入特定信息的字段。在表结构中表现为attribute_category、attribute1字段等。

      注册关键性弹性域

      注册说明性弹性域

      1.创建数据表。

      注:使用说明性弹性域的数据表,必须含有ATTRIBUTE_CATEGORY及若干ATTRIBUTEN字段。 ATTRIBUTE_CATEGORY字段:指弹性域的CONTEXT字段。 ATTRIBUTEN字段:指实际使用的字段。

      create table HEK_DISCOUNT_POLICY_H_NEW(

      POLICY_ID NUMBER, POLICY_NO VARCHAR2(30) not null, CUSTOMER_ID NUMBER, CUSTOMER_NUMBER NUMBER , CUSTOMER_NAME VARCHAR2(100), BENIFICIARY_ID NUMBER, BENIFICIARY_NUMBER NUMBER , BENIFICIARY_NAME VARCHAR2(100), RELATION_NUMBER NUMBER , RELATION_NAME VARCHAR2(100), PAYMENT_TYPE VARCHAR2(20), POLICY_PERIOD VARCHAR2(20) not null, ATTRIBUTE_CATEGORY VARCHAR2(150), ATTRIBUTE1 VARCHAR2(150), ATTRIBUTE2 VARCHAR2(150), ATTRIBUTE3 VARCHAR2(150), CREATED_BY NUMBER, CREATION_DATTE DATE, LAST_UPDATED_BY NUMBER, LAST_UPDATE_DATE DATE, LAST_UPDATE_LOGIN NUMBER)

      2.注册弹性域表

      begin

      ad_dd.register_table('HEK','HEK_DISCOUNT_POLICY_H_NEW','T',10,10,40);

      commit;

      end;

      3.注册弹性域表的列

      begin

      ad_dd.register_column('HEK','HEK_DISCOUNT_POLICY_H_NEW','ATTRIBUTE_CATEGORY',1,'VARCHAR2',150,'N','N'); ad_dd.register_column('HEK','HEK_DISCOUNT_POLICY_H_NEW','ATTRIBUTE1',2,'VARCHAR2',150,'N','N'); ad_dd.register_column('HEK','HEK_DISCOUNT_POLICY_H_NEW','ATTRIBUTE2',3,'VARCHAR2',150,'N','N'); ad_dd.register_column('HEK','HEK_DISCOUNT_POLICY_H_NEW','ATTRIBUTE3',4,'VARCHAR2',150,'N','N');

      commit;

      end;

      4.查看是否注册成功

      select ft.table_id from FND_TABLES ft where ft.table_name='HEK_DISCOUNT_POLICY_H_NEW'

      select * from FND_COLUMNS fc where fc.table_id in (select ft.table_id from FND_TABLES ft where ft.table_name='HEK_DISCOUNT_POLICY_H_NEW')

      5.注册弹性域列 操作路径:应用开发员=>弹性域=>说明性=>注册

      

      点列按钮,选择注册相应的列

      

      6. 注册弹性域段

      

      点段按钮,输入提示文本

      

      7.启用说明性弹性域

      7.1先按将相应的FORM开发好,然后在FORM级的以下TRIGGER中加入

      PRE-QUERY: FND_FLEX.EVENT('PRE-QUERY');

      POST-QUERY: FND_FLEX.EVENT('POST-QUERY');

      PRE-INSERT: FND_FLEX.EVENT('PRE-INSERT');

      PRE-UPDATE : FND_FLEX.EVENT('PRE-UPDATE');

      WHEN-VALIDATE-ITEM: FND_FLEX.EVENT('WHEN-VALIDATE-ITEM');

      WHEN-VALIDATE-RECORD: FND_FLEX.EVENT('WHEN-VALIDATE-RECORD');

      7.2在PRE-FORM的TRIGGER中加入

      fnd_descr_flex.define ( BLOCK=>'HEK_DISCOUNT_POLICY_H_NEW',

      FIELD=>'DESC_FLEX',

      APPL_SHORT_NAME=>'HEK',

      DESC_FLEX_NAME=>'HEK返利_订金');

      说明一下相应参数:BLOCK:指启用弹性域的数据块名 FIELD:指后面新增的ITEM APPL_SHORT_NAME:指相应模块的简称(系统管理员->应用->注册) DESC_FLEX_NAME:指注册弹性域时的名称

      8.在要启用弹性域的数据块中增加一个ITEM。名称为:DESC_FLEX。

      8.1 DESC_FLEX属性设置如下:

      子类信息:TEXT_ITEM_DESC_FLEX

      数据库项:否

      画布:MAIN_C

      8.2在DESC_FLEX项的以下trigger中加入:

      WHEN-VALIDATE-ITEM :FND_FLEX.EVENT('WHEN-VALIDATE-ITEM');

      WHEN-NEW-ITEM-INSTANCE:FND_FLEX.EVENT('WHEN-NEW-ITEM-INSTANCE');

      9.完成效果:

      

      条件控制说明性弹性域

      说明:通过一个字段的值控制是否显示说明性弹性域。与普通的说明性弹性域类似。下面仅说明不同之处。

      1. 注册弹性域列时,定义一个参考列。

      

      点击参考字段按钮

      

      DISCOUNT_TYPE是要启用弹性域数据表中的一个字段,即通过这个字段,来控制是否显示弹性域。

      2.定义弹性域段

      

      新增一条上下文值记录,例:年返。即当DISCOUNT_TYPE的值为“年返”时,才显示弹性域。

      

      3.实现效果。

      

      调用会计科目弹性域

      1.首先在创建数据表时,添一个字段用来保存会计科目的ID。如:CODE_COMBINATION_ID

      2.在FORM相应的数据块增加两个ITEM,用来显示科目NUMBER与DESCRITION。

      例:GL_CODE_NUMBER、GL_CODE_DESC

      注 : ENABLE_LIST_LAMP是TEMPLATE模板自带的,无须手工去定义。 将GL_CODE_NUMBER项的LOV设成“ENABLE_LIST_LAMP”,数据库项设为“否”。 将GL_CODE_NUMBER“从列表中验证”属性设成否。

      3.在Form Level 的WHEN-NEW-FORM-INSTANCE Trigger初始化弹性域

      FND_KEY_FLEX.DEFINE(BLOCK => 'BlockName ',

      FIELD => 'GL_CODE_NUMBER',

      ID => 'CODE_COMBINATION_ID',

      DESCRIPTION => 'GL_CODE_DESC',

      APPL_SHORT_NAME => 'SQLGL',

      CODE => 'GL#', NUM => 101, --STRUCTURE Number REQUIRED => 'N' );

      说明:APPL_SHORT_NAME查找:系统管理员=>应用=>注册

      

      CODE查找:应用开发员=>键=>注册

      

      NUM查

      

      4.可以在GL_CODE_NUMBER项的WHEN-VALIDATE-ITEM触发器中,对所选择的科目进行核查。

      IF : BlockName.CODE_COMBINATION_ID = -1 then

      fnd_message.debug('所选科目组合无效!');

      raise form_trigger_failure;

      end if;

      5、完成效果:

      

      键弹性域与说明性弹性域明显的区别。就是使用键弹性域的数据表只保留了ID。以会计科目弹性域为例,数据表只保存了ID(即CODE_COMBINATION_ID,这个字段是对应会计科目的ID)。GL_CODE_NUMBER、GL_CODE_DESC都只是控制块的ITEM,通过CODE_COMBINATION_ID来查询对应的科目。

      EBS11i FormMVC模式

      一个同事在的视频会议上提到,在做EBS开发时,要用MVC模式来满足不断在变化的业务需求。很有意思的话题,值得展开讨论。JAVA设计模式的书偶看了N次,但只会在JAVA应用,但从未想过在其他的4GL编程语言实现。以下是我的理解。 首先,按JAVA的那一套,MVC是指MODEL(模型层)、VIEW(表现层)、CONTROLLER(控制层)的缩写。编写软件为什么分层,这个是软件工程的需求。也就是说分层的目的是提高软件的可维护性,避免“动一牵百”的修改软件。 其次,按照这种软件分层原理,在JAVA中比较容易实现。Struts就是这类比较典型应用。模型层可以用实体类来实现,表现层可以用JSP+STRUTS标签实现,控制层可以action类实现。那么在ORACL FORMS如何实现分层呢?以下对号入座的想法。 MODEL用数据块来实现、VIEW用FORM界面实现、控制层呢?MVC中最为关键的是CONTROLLER。因为CONTROLLER实现业务逻辑与流程流转。并且按照设计模式的要求,CONTROLLER又被分成若干小层,如DAO层、SERVICES层等等,并且带来的“面向接口编程”之方法。ORACLE FORM实现业务逻辑与界面分离是通过程序单元来实现,控制层具体表现在ORACLE FORMS当中没有,只能通过繁琐的PL/SQL语句实现。 不知道这种理解对不对。这个话题是很有意思的,大家觉得呢?欢迎讨论哦。

      EBS预警功能自定义开发

      EBS预警分为事件预警和定期预警。预警功能非常强大,本例以订单录入后,以邮件的形式通知财务主管进行“订单登记”审核。

      1、 定义预警。

      操作路径:预警系统管理器=>预警=>定义

      

      2、 编写SQL语句(注:SQL必须包含INTO、where rowid=:rowid)

      select ORDER_NUMBER into &order_number from OE_ORDER_HEADERS_all head WHERE rowid = :ROWID

      

      3、 点击上图中的“活动按钮”。

      

      4、 点击上图中的“活动详细资料”按钮。

      

      5、 定义活动集。

      

      6、 预警安装

      

      点击“预警详细资料”按钮。

      

      7、 完成效果如下:

      

      EBS自定义邮件通知

      前面已经介绍过了EBS预警的功能,事实上Oracle数据库本身就有提供UTL_SIMPLE(ORACLE10g以后变成UTL_MAIL)包来实现邮件发送的功能,利用这个包可以开发出更灵活东西来。首先要安装utlsmtp.sql、utltcp.sql这两个包。

      ①发送带有URL邮件代码

      declare

      p_sender varchar2(30) := 'chongdong_wang@hek.cn';

      p_recipient varchar2(30) := 'jian_li2@hek.cn';

      p_subject varchar2(50) := '使用PL/SQL发送邮件';

      p_body long := '这是邮件正文内容啦!我又来啦!!!进行ORACLE ERP';

      mail_conn utl_smtp.connection;

      mail_host varchar2(15) := 'mail.hek.cn';

      user_name varchar2(156) := 'chongdong_wang@hek.cn';

      user_pwd varchar2(156) := '***';

      begin --创建一个TCP MAIL连接

      mail_conn := utl_smtp.open_connection(mail_host, 25);

      --ehlo与helo的区别:是否对邮件主机进行登陆认证

      --utl_smtp.helo(main_conn,mail_host);

      utl_smtp.ehlo(mail_conn, mail_host);

      --登陆认证语句 utl_smtp.command(mail_conn, 'AUTH LOGIN');

      --对用户及密码进行加密

      utl_smtp.command(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_name)));

      utl_smtp.command(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_pwd)));

      --指定发件人 utl_smtp.mail(mail_conn, p_sender);

      --指定收件人 utl_smtp.rcpt(mail_conn, p_recipient);

      --开始写邮件内容 utl_smtp.open_data(mail_conn);

      --指定显示的发件人,注意这边的显示的发件人可以上面指定发件人不同

      --这实际上是SMTP协议的缺陷,也是造成垃圾邮件主要原因

      utl_smtp.write_data(mail_conn, 'From:' || p_sender || utl_tcp.CRLF); utl_smtp.write_data(mail_conn, 'To:' || p_recipient || utl_tcp.crlf);

      --邮件主题:中文必须进行编码转换,否则会乱码 utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert('Subject:' || p_subject || utl_tcp.CRLF, 'ZHS16GBK')));

      --设置邮件内容模式为HTML,也可以直接设置文本Content-Type:text/plain

      utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert('Content-Type:text/html;

      charset=GBK' || utl_tcp.CRLF, 'ZHS16GBK')));

      utl_smtp.write_data(mail_conn, utl_tcp.CRLF);

      --邮件正文 utl_smtp.write_raw_data(mail_conn, utl_raw.cast_to_raw(convert(p_body, 'ZHS16GBK')));

      --关闭连接 utl_smtp.close_data(mail_conn); utl_smtp.quit(mail_conn); exception when utl_smtp.transient_error or utl_smtp.permanent_error then utl_smtp.quit(mail_conn);

      raise_application_error(-20000, sqlerrm);

      when others then raise_application_error(-20001, 'The send mail was error ' || sqlerrm);

      end;

      ②发送带有附件的邮件

      declare

      p_sender varchar2(30) := 'metalink@hek.cn';

      p_recipient varchar2(30) := 'chongdong_wang@hek.cn';

      p_subject varchar2(50) := 'PL/SQL发邮件、带链接、带附件';

      p_body long := 'PL/SQL发邮件、带链接带附件

      这是邮件正文内容啦!这是带附件的啦!!

      进行ORACLE ERP';

      mail_conn utl_smtp.connection;

      mail_host varchar2(15) := 'mail.hek.cn';

      user_name varchar2(156) := 'metalink@hek.cn';

      user_pwd varchar2(156) := 'metalink'; --发附件要用到的变量

      L_FIL BFILE; L_FILE_LEN NUMBER;

      L_MODULO NUMBER; L_PIECES NUMBER;

      L_FILE_HANDLE UTL_FILE.FILE_TYPE;

      L_AMT BINARY_INTEGER:=672*3;/* ensures proper format; 2016 */

      L_FILEPOS PLS_INTEGER:=1;/* pointer for the file */

      L_CHUNKS NUMBER; L_BUF RAW(2100); L_DATA RAW(2100);

      L_MAX_LINE_WIDTH NUMBER:=54; L_LINE VARCHAR2(1000);

      L_MESG VARCHAR2(32767);

      BOUNDARY CONSTANT VARCHAR2(256) := '-----7D81B75CCC90D2974F7A1CBD';

      FIRST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || utl_tcp.CRLF;

      LAST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || '--' || utl_tcp.CRLF;

      --发送带有附件邮件,MIME必须设为multipart/mixed

      MULTIPART_MIME_TYPE CONSTANT VARCHAR2(256) := 'multipart/mixed; boundary="'|| BOUNDARY || '"';

      begin

      --创建一个TCP MAIL连接

      mail_conn := utl_smtp.open_connection(mail_host, 25);

      --ehlo与helo的区别:是否对邮件主机进行登陆认证 -

      -utl_smtp.helo(main_conn,mail_host);

      utl_smtp.ehlo(mail_conn, mail_host);

      --登陆认证语句 utl_smtp.command(mail_conn, 'AUTH LOGIN');

      --对用户及密码进行加密

      utl_smtp.command(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_name)));

      utl_smtp.command(mail_conn, demo_base64.encode(utl_raw.cast_to_raw(user_pwd)));

      --指定发件人

      utl_smtp.mail(mail_conn, p_sender); --指定收件人

      utl_smtp.rcpt(mail_conn, p_recipient); --开始写邮件内容

      utl_smtp.open_data(mail_conn);

      utl_smtp.write_data(mail_conn, 'From:' || p_sender || utl_tcp.CRLF);

      utl_smtp.write_data(mail_conn, 'To:' || p_recipient || utl_tcp.crlf);

      utl_smtp.write_data(mail_conn, 'Subject: ' || p_subject || utl_tcp.crlf);

      --中文编码转换

      utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Subject:' ||p_subject ||utl_tcp.CRLF,'ZHS16GBK'))); utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:'||MULTIPART_MIME_TYPE||utl_tcp.CRLF,'ZHS16GBK')));

      --utl_tcp.CRLF 数据流行尾符

      utl_smtp.write_data(mail_conn, utl_tcp.CRLF); -

      -邮件正文

      utl_smtp.write_data(mail_CONN, FIRST_BOUNDARY);

      utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:text/html;charset=GB2312' ||utl_tcp.CRLF, 'ZHS16GBK')));

      utl_smtp.write_data(mail_conn, utl_tcp.CRLF);

      utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert(p_body, 'ZHS16GBK')));

      utl_smtp.write_data(mail_conn, utl_tcp.CRLF);

      --附件格式

      utl_smtp.write_data(mail_CONN, FIRST_BOUNDARY);

      utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Type:text/html;charset=GB2312' ||utl_tcp.CRLF, 'ZHS16GBK')));

      utl_smtp.WRITE_RAW_DATA(mail_conn, UTL_RAW.CAST_TO_RAW(CONVERT('Content-Disposition' || ':' ||'attachment;filename="'||'qq.xls"' || utl_tcp.CRLF, 'ZHS16GBK')));

      utl_smtp.write_raw_data(mail_conn,utl_raw.cast_to_raw(convert('Content-Transfer-Encoding:base64'||utl_tcp.CRLF,'ZHS16GBK')));

      utl_smtp.write_data(mail_CONN, UTL_TCP.CRLF);

      --附件二进制流

      BEGIN

      --把附件分成多份,这样可以发送超过32K的附件

      L_FILEPOS := 1;

      --CREATE OR REPLACE DIRECTORY U_FIEL AS '/data/book/'

      --qq.xls附件放在ORACLE服务器/data/book/下,注意大写

      L_FIL := BFILENAME('U_FIEL', 'qq.xls');

      L_FILE_LEN := DBMS_LOB.GETLENGTH(L_FIL);

      L_MODULO := MOD(L_FILE_LEN, L_AMT);

      L_PIECES := TRUNC(L_FILE_LEN / L_AMT);

      IF (L_MODULO <> 0) THEN L_PIECES := L_PIECES + 1; END IF;

      DBMS_LOB.FILEOPEN(L_FIL, DBMS_LOB.FILE_READONLY);

      DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF);

      L_DATA := NULL; FOR I IN 1 .. L_PIECES LOOP L_FILEPOS := I * L_AMT + 1;

      L_FILE_LEN := L_FILE_LEN - L_AMT;

      L_DATA := UTL_RAW.CONCAT(L_DATA, L_BUF);

      L_CHUNKS := TRUNC(UTL_RAW.LENGTH(L_DATA) / L_MAX_LINE_WIDTH);

      IF (I <> L_PIECES) THEN L_CHUNKS := L_CHUNKS - 1;

      END IF;

      utl_smtp.write_raw_data(MAIL_CONN, UTL_ENCODE.BASE64_ENCODE(L_DATA));

      L_DATA := NULL;

      IF (L_FILE_LEN < L_AMT AND L_FILE_LEN > 0) THEN L_AMT := L_FILE_LEN;

      END IF;

      DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF);

      END LOOP;

      DBMS_LOB.FILECLOSE(L_FIL);

      EXCEPTION WHEN OTHERS THEN DBMS_LOB.FILECLOSE(L_FIL);

      utl_smtp.WRITE_DATA(mail_CONN, UTL_TCP.CRLF);

      RAISE;

      END;

      --结束处理二进制附件

      --关闭连接

      utl_smtp.close_data(mail_conn); utl_smtp.quit(mail_conn);

      exception when utl_smtp.transient_error or

      utl_smtp.permanent_error then utl_smtp.quit(mail_conn);

      raise_application_error(-20000, sqlerrm);

      when others then

      utl_smtp.quit(mail_conn);

      DBMS_OUTPUT.put_line(sqlerrm);

      end;

      EBS配置文件(Profile)常用设置

      

      IE打不开EBS

      ①症状:一直停留在EBS弹出式窗体,显示正在加载FORMS。

      解决:安装SUN JDK1.4,并将JVM.DLL替换掉X:Program FilesOracleJInitiator 1.3.1.21binhotspot

      ②症状:无法查看工作流状态图(view datagram)

      解决:安装微软的虚拟机msjavx86.exe。

      获取EBS的查询语句

      1.帮助=>诊断=>检查

      

      2.在块中输入SYSTEM、在字段中输入LAST_QUERY,就可以得到查询的SQL语句。

      

    ############################## 通往精神的路很多,物质只是其中一种 ##############################
    http://www.onejava.com/article/oracle/wip/wiptop.htm
    https://docs.oracle.com/cd/A60725_05/html/comnls/us/index.htm
    http://www.oracle.com/technetwork/cn/developer-tools/apex/getting-started-094884-zhs.html
    https://docs.oracle.com/cd/B34956_01/current/html/docset.html
  • 相关阅读:
    Django源码解析(1):启动程序
    python之importlib模块
    Django中间件:CsrfViewMiddleware
    Django的admin组件
    Linux学习之CentOS--CentOS6.4下Mysql数据库的安装与配置【转】
    C#读取Xml【转】
    在eclipse导入项目的步骤【转】
    Spring学习(一)——Spring中的依赖注入简介【转】
    Spring学习(二)——Spring中的AOP的初步理解[转]
    Spring之AOP
  • 原文地址:https://www.cnblogs.com/pompeii2008/p/5309956.html
Copyright © 2011-2022 走看看