数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

开发篇之—Oracle触发器心得体会


发布日期:2022年04月20日
 
开发篇之—Oracle触发器心得体会

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

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

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

Masterdetail关系

block both are database block

each block has one item based on database displayed

在PL/SQL Develop中没有环境变量所以如果要查询多组织的View需要先执行设置环境变量函数:

BEGIN

fnd_client_infoset_org_context();

END;

GLOBAL变量对于所有form有效(可能是同一个应用这个尚未验证)而不仅仅是你所开发的form变量比如Global和Parameter的初始化应该在preform里面在whennewforminstance里面初始化不行因为whennewforminstance是在进入第一个导航块的第一个item之后才促发的没有属性指名Block的记录数不过可以通过GET_BLOCK_PROPERTY(QUERY_HITS) 取得查询到的记录数hide_view并没有真正hide一个画布只是放到最下层所以如果上层的画布没有完全覆盖下层画布下层的画布很可能用户还看得到show_view则是把画布放在最上层

lov验证的时候是验证第一个可见的列并且会把其他的返回值返回给各个Item而不是仅仅验证而已lov的查询一般是针对第一列但是如果我们把%放在最前面则可以查询所有列

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

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

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

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

Trigger顺序

precommit

的preinsertoninsertpostinsert

的preinsertoninsertpostinsert

postformscommit

Trigger顺序

whenlistchanged在前Validation item在后因为Validation item是在要离开这个item的时候才促发的

Trigger顺序

preform/whencreaterecord/preblock/

whennewformsinstance/whenvalidaterecord/oninsert/postforms

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

Trigger顺序

postchanged在whenvalidateitem之前所有的whenvalidate事件是当forms自己验证通过之后才促发的

禁用Clear功能可以通过在Form的keyclrblk里面调用app_exceptiondisabled其实只是用Bell覆盖默认的执行

直接放在TAB Page上的Item和放在堆叠画布上的Item在设计时是无法所见即所得所以建议把所有的Item根据需要放在不同的堆叠画布上再堆到TAB Page上伪列Rownum在排序之前就已经决定如果想得到排序后的Rownum应当在嵌套一个Select语句另外Where语句中的rownum只能用<或者<=不能有>或者>=

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

同事在装i的时候连安装界面都没出来而我机器可以装后来才知道原来他的机器是P无法正常安装

实际执行的Where条件是我们设置DEFAULT_WHERE再加上通过赋过值的Item

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

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

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

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

一般来说系统变量是很好用的然而有时候并非如此比如Current_Recordget_block_property(blocknameCurrent_Record)的结果并非总是一样的后者更加保险!特别是刚打开Form的时候在WHENNEWRECORDINSTANCE里面前者是后者是

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

重启Application

cd ?$APPLCSF

cd scripts

cd PROD

/adstpallsh apps/apps

/adstrtalsh apps/apps

Trigger顺序

postquery只有在界面可见的记录才会促发记录从不可见变为可见时促发促发过的记录不再促发

保存的时候会引发Post Item/Record/Block事件因为要Navigate到Form

数据库org_id初始值to_number(decode(substrb(userenv(CLIENT_INFO)) nullsubstrb(userenv(CLIENT_INFO))))

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

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

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

上一篇:数据库名、实例名、ORACLE

下一篇:ORACLE SGA 的分配