壹佰网|ERP100 - 企业信息化知识门户

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1363|回复: 6

[二次开发] 为什么在视图里fnd_global.ORG_ID取不到值,fnd_profile.VALUE('ORG_ID')却能取到值

[复制链接]
发表于 2013/1/9 21:50:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。如果您注册时有任何问题请联系客服QQ: 83569622  。

您需要 登录 才可以下载或查看,没有帐号?注册

x
为什么在视图里fnd_global.ORG_ID取不到值,fnd_profile.VALUE('ORG_ID')却能取到值呢?这两者的区别在哪里?

该贴已经同步到 rfb0204421的微博
发表于 2013/1/10 05:57:48 | 显示全部楼层
希望对你有帮助

fnd_profile.value的用法:
select fnd_profile.value('gl_set_of_books_id')
   from dual
select fnd_profile.value('mfg_organization_id')
   from dual   --取子库
select fnd_profile.value('GL_SET_OF_BKS_ID')
   from dual--取帐套  

用此方式調整正確的當前咝协h境,特別是在multi_org環境下(在報表前,報表後均要執行因有可能在咝羞^程中變量被人為改變)
有一些view用到org環境參數的,一般要如下設定後,才能select到記錄:
begin
dbms_application_info.set_client_info(:org_id);--如1,2,3之類的
end;

可用'FND_PROFILE.GET' function 查看以下一些參數
取得set of book id
Select fnd_profile.value('GL_SET_OF_BKS_ID') from dual

取得master_id
select fnd_profile.value('SO_ORGANIZATION_ID') from dual;

取得當前org_id
select to_number(fnd_profile.value('ORG_ID')) from dual;

org_id = :$PROFILES$.ORG_ID;也可用此來取得,在定義報表參數時來定義
fnd_profile.value('MFG_ORGANIZATION_ID') 與上的區別

取得當前user_id
select TO_NUMBER(FND_PROFILE.VALUE('USER_ID')) from dual;
FND_GLOBAL.USER_ID 用此方式在report中有可能不好用,在report中建議用上一種方式FND_WHO.PROFILE('USERID') 又一種方式取得當前login_id

select TO_NUMBER(FND_PROFILE.VALUE('login_ID')) from dual;

取得當前username
Declare
username varchar2(30);
begin
username := FND_PROFILE.VALUE('USERNAME');
end;

另獲取username 也可以用FND_Global.User_Name
fnd_global package可以取得一些關於當前login in用戶的信息

取得當前request_id
select FND_PROFILE.VALUE('CONCURRENT_REQUEST_ID') from dual;

FND_REQUEST.SUBMIT_REQUEST 另一種方式
請看fnd_concurrent_requests functions
在PL/SQL Develop中没有环境变量,所以如果要查询多组织的View,需要先执行设置环境变量函数
dbms_application_info.set_client_info(81);end;与 BEGIN    fnd_client_info.set_org_context(82)END; 效果一样,这个81是指OU_ID,业务实体的ID .
发表于 2013/1/10 05:59:55 | 显示全部楼层
fnd_global.apps_initialize(user_ID, Responsibility_id,
                                          Responsibility_application_id);
作用:在数据库的会话中设置全局变量,和用户概要信息。
参数获得:
参数一,用户号
    select user_id
    from fnd_user
    where user_name like '%OPERATIONS%'; -- ID of OPERATIONS:1318
参数二,职责编号(responsibility id)
    select RESPONSIBILITY_ID, APPLICATION_ID, RESPONSIBILITY_KEY
    from fnd_responsibility
    --where APPLICATION_ID = 140
    where RESPONSIBILITY_KEY like '%ASSETS_VISION_OPERATIONS%';
参数三,代表该职责所属的应用程序(application)的编号
    上面的SQL取得
方便的方法:Help->Diagnostics->Examin, Block: $PROFILES$, Field: RESP_ID(以及其他的)
运行:
BEGIN
fnd_global.APPS_INITIALIZE(youruesr_id, yourresp_id, yourresp_appl_id);
END;
测试:
select fnd_profile.value('GL_SET_OF_BKS_ID') FROM DUAL;
select fnd_profile.value('USER_ID') from dual; --对应刚才的user_id
 楼主| 发表于 2013/1/10 09:03:27 | 显示全部楼层
纵横四海 发表于 2013/1/10 05:59
fnd_global.apps_initialize(user_ID, Responsibility_id,
                                          R ...

谢谢四海哥耐心的回答,不过我现在的情况是这样的,我不是想直接在PL/SQL中查询这个视图,而是在FORM中使用。我是在建立这个视图的where条件后面加了xxx=fnd_global.ORG_ID,然后在FORM使用这个视图,但是查询不到数据,后来跟踪到fnd_global.ORG_ID返回的是-1.后面我把视图的where条件改为fnd_profile.VALUE('ORG_ID'),就可以取到数据了,我百思不得其解。

点评

我不做Form开发,所以只是給你找找资料;嘿嘿  发表于 2013/1/10 09:31
发表于 2013/1/10 09:24:18 | 显示全部楼层
rfb0204421 发表于 2013/1/10 09:03
谢谢四海哥耐心的回答,不过我现在的情况是这样的,我不是想直接在PL/SQL中查询这个视图,而是在FORM中使 ...

在网络上給你找到一篇

实在对象如表格、Sequence、索引等建在本应用对应的用户表空间中,其他对象如视图、别名创建在Apps下,常见错误是新手把表建在APPS下,以后又来建别名,这个时候删除别名时会报对象不存在,而建别名的时候又报对象已存在

如果把脚本保存在文件里面,注意一个块比如一个创建视图的语句不要有空行,否则会出现如下情况:把语句拷贝到SQL Window能正常运行,用@执行文件却报错

如果要执行execute_query,注意要go_block到适当的Block,但是go_block是个受限过程,并不一定都能成功

Master-detail关系
block both are database block
each block has one item based on database displayed

在PL/SQL Develop中没有环境变量,所以如果要查询多组织的View,需要先执行设置环境变量函数
declare
  x_org_id number;
begin
   Fnd_profile.GET('ORG_ID',x_org_id);
   fnd_client_info.set_org_context(x_org_id);
end;

GLOBAL变量对于所有form有效(可能是同一个应用,这个尚未验证),而不仅仅是你所开发的form

变量比如Global和Parameter的初始化应该在pre-form里面,在when-new-form-instance里面初始化不行,因为when-new-form-instance是在进入第一个导航块的第一个item之后才促发的

没有属性指明Block的记录数,不过可以通过GET_BLOCK_PROPERTY(QUERY_HITS) 取得查询到的记录数

hide_view并没有真正hide一个画布,只是放到最下层,所以如果上层的画布没有完全覆盖下层画布,下层的画布很可能用户还看得到;show_view则是把画布放在最上层

lov验证的时候是验证第一个可见的列,并且会把其他的返回值返回给各个Item,而不是仅仅验证而已

Tip:lov的查询一般是针对第一列,但是如果我们把%放在最前面,则可以查询所有列

用Execute_query执行查询的时候,会把Copy Value From Item里面的那个Item的值自动作为查询条件。当创建记录的时候也会直接用该值初始化,而且不改变记录的状态。在更新记录的时候不知道会不会Copy过来尚未验证。Get_Item_property的时候用ENFORCE_KEY属性,但不能Set。该属性在Master-detail设置的时候自动创建,删除的时候自动删除。如果不希望Copy Value From Item影响查询结果,可以在Pre-Query里面把Item的值设为null。

app_query.reset('block_name');如果第一次调用,会把当前的DEFAULT_WHERE,然后什么都不做,以后再来调用的时候则会把第一次设置的DEFAULT_WHERE用set_block_property('SAA_HEADERS',DEFAULT_WHERE,...)设置回来,具体请参考app_core库

When-create-record的时候给Item赋值不改变记录状态

Sequence,如果我们在Item的Initial Value里面赋值,那么假如用户Focus To新记录,又回到老记录,如此反复,Sequence会不断变大的

SQL Order BY的时候null值排在最后,这个一般不符合实际要求,可以这样解决ORDER BY nvl(Geography_Code,chr(0))解决

Trigger顺序1
pre-commit
  块1的pre-delete,on-delete,post-delete(一条一下)
  块1的pre-insert,on-insert,post-insert(一条一下)
  块1的pre-update,on-update,post-update(一条一下)
  块2的pre-delete,on-delete,post-delete(一条一下)
  块2的pre-insert,on-insert,post-insert(一条一下)
  块2的pre-update,on-update,post-update(一条一下)
  ...
post-forms-commit(不管有没有操作,都要发生!而且只有一次)
on-commit
post-database-commit

Trigger顺序2
when-list-changed在前,Validation item在后,因为Validation item是在要离开这个item的时候才促发的

Trigger顺序3
pre-form/when-create-record/pre-block/when-new-forms-instance/when-validate-record/on-insert/post-forms

当定位到主块的一个记录,会促发子块的when-clear-record事件和when-create-record事件,问题是如果主块的是新记录(未保存),在子块的when-create-record里面取主块的任何东西,居然是主块的上一次获得焦点的记录的东西;连用取块的当前记录也是上一次获得焦点的记录

Trigger顺序4
post-changed在when-validate-item之前
所有的when-validate事件是当forms自己验证通过之后才促发的

禁用Clear功能可以通过在Form的key-clrblk里面调用app_exception.disabled,其实只是用Bell覆盖默认的执行

直接放在TAB Page上的Item,和放在堆叠画布上的Item在设计时是无法“所见即所得”,所以建议把所有的Item根据需要放在不同的堆叠画布上再堆到TAB Page上

伪列Rownum在排序之前就已经决定,如果想得到排序后的Rownum,应当在嵌套一个Select语句;另外Where语句中的rownum只能用<或者<=,不能有>或者>=

在SQL中用Over的时候,如果整个语句没有Order by语句,最后的结果还是会排序的,规则是先按Over里面的Partition排序,再按Over里面的Order by排序。原因可能和分析函数的处理顺序有关(8ifunctions.pdf有详细介绍):先查询到数据(Join/Where/Group By/Having),再运算分析函数(先分区,然后排序,再算Slide Windows,最后计算),最后是Order By。另外,一个疑问:我测试到的一个结果Group By好像无法影响Partition,可是按照8ifunctions.pdf的说法,应该先执行Group By的,是不是因为Group By只是在第一阶段的处理时作用在集合函数上,之后进入第二阶段的处理就没用了。

同事在装8i的时候,连安装界面都没出来,而我机器可以装,后来才知道原来他的机器是P4,无法正常安装,记得以前看过一篇文章,讲如何在P4上安装;近期又看到Oracle彻底解决8iP4安装问题

实际执行的Where条件,是我们设置DEFAULT_WHERE,再加上通过赋过值的Item。注意APP_FIND.query_range已经重载过,我们调用的时候可以不区分query_number_range或者query_date_range;观察其代码,发现也是通过给Item赋值来影响查询的,只不过是赋值的时候,可能是加上 # between,# >=或# <=;这样导致的一个结果是:Date类型的Item长度默认是11,被query_range这样一搞,长度根本不够,于是就导致诸如where REQUEST_DATE >= to_dat的错误,所以记得把字段长度加长,比如1000;总的来说,碰到From to的要小心长度。

当修改子类的时候,会自动更改很多属性,特别是Required,一定要注意

当对块进行刷新时,会修改很多Item的属性,别以为你设置过了,Oracle就会记住。我碰到的情况是Insert Allowed等被自动改掉了!即使我的子类设置为Text_Item_Display_Only

当拷贝Item的时候,也有些问题,比如日期和关键弹性域的Validate-from-list会变成Yes

两个变量,如果都为Null,判断还是不相等,所以必须用 a1 is null and a2 is null。所以在On-lock里面的if条件,我们可以把所以不可以为空的字段都写成允许为空的形式。

一般来说,系统变量是很好用的。然而有时候并非如此,比如Current_Record,get_block_property('blockname',Current_Record)的结果并非总是一样的,后者更加保险!特别是刚打开Form的时候,在WHEN-NEW-RECORD-INSTANCE里面,前者是0,后者是1

''''表示一个单引号,''''''表示两个单引号。应该是这样理解,一个单引号表示转义字符,首尾两个单引号里面的内容表示字符串。

重启Application
cd $APPLCSF
cd scripts
cd PROD
./adstpall.sh apps/apps
./adstrtal.sh apps/apps

Trigger顺序5
post-query,只有在界面可见的记录才会促发,记录从不可见变为可见时促发,促发过的记录不再促发;
保存的时候会引发Post Item/Record/Block事件,因为要Navigate到Form

数据库org_id初始值to_number(decode(substrb(userenv('CLIENT_INFO'),1,1),' ',null,substrb(userenv('CLIENT_INFO'),1,10)))

给非数据库Item赋值,
new记录会变成insert(所以就不能F11了)
query/changed记录不变
new块会变成query
query/changed块不变

对On-lock的理解,由于先入为主的缘故,开始一直很苦恼,为什么If里面只用了一个Return,Form怎么知道要锁否?后来才知道On类型的数据库触发器是替换型的,On-lock也不例外,所以只要On-lock不Raise什么东西出来,Form就认为是锁成功了,至于实际的锁,我们有Select……For Update来完成,至于If判断只是进行更加严格的判定。

对Find的理解,开始也很纳闷,为什么在Pre-query里面直接给Item赋值就可,不用自己拼语句,现在也逐渐发现里面大有文章。回想F11,这个时候的block其实是处于Enter-query状态,输入的东西Form会自动拼成Where语句(当然还要加上原来的default where,如果有Copy from item,也要加上),对于每个Item上输入的值,一般是用 = ,如果有,就解析为like,如果有#,则把后边的表达式(比如between,甚至是子查询)直接作为条件;而当form内部执行堆栈Navigate到Pre-query时,block也是处于Enter-query状态,道理和F11一样,我们只管按业务查询要求对Item赋值,剩下的就交给Form去处理了;需要注意的是当处于enter-query状态的block,是使用query length属性来限制输入的数据长度,而不是通常的maximum lengh,只不过query length默认是0,即等于maximum lengh,所以会出现当用app_find.query_range时长度不够的情况。

二次开发中自定义菜单的使用需要在三个地方写代码form when-new-form-instance/app_special.instantiate('SPECIAL1','prompt'),form pre_block/app_special.enable('SPECIAL1',property_on),form SPECIAL1 trigger/菜单需要执行的代码
发表于 2013/5/28 16:01:51 | 显示全部楼层
rfb0204421 发表于 2013/1/10 09:03
谢谢四海哥耐心的回答,不过我现在的情况是这样的,我不是想直接在PL/SQL中查询这个视图,而是在FORM中使 ...

增加Choose ORG功能:
在form level 的trigger中的pre—form中加上FND_ORG.CHOOSE_ORG;


发表于 2013/5/29 09:54:32 | 显示全部楼层
四海兄弟不错,赞一个!
此帖子看了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|手机版|壹佰网 ERP100 ( 京ICP备19053597号-2 )

Copyright © 2005-2012 北京海之大网络技术有限责任公司 服务器托管由互联互通
手机:13911575376
网站技术点击发送消息给对方83569622   广告&合作 点击发送消息给对方27675401   点击发送消息给对方634043306   咨询及人才点击发送消息给对方138011526

GMT+8, 2025/11/29 13:29 , Processed in 0.019510 second(s), 16 queries , File On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表