ImageVerifierCode 换一换
格式:DOCX , 页数:6 ,大小:25.77KB ,
资源ID:17286010      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/17286010.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Oracle生成代理键的方法页1Word文档格式.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Oracle生成代理键的方法页1Word文档格式.docx

1、Referencing New AS New Old AS OldFor Each RowDeclarenTmpID number(10,0);BeginSelect se_tablename_idcolname.NEXTVAL intonTmpID from dual;:new.idcolname:=nTmpID;End; 这种方法的缺点是:需要为每个表创建一个对应的序列和一个对应的触发器。序列:虽然一个序列可以为多个表提供值但这样会使数值增加速 度以及达到最大值的速度成倍增长。因此还是需要为每个表 创建一个序列。序列值会在生成过程中产生漏洞,同样用过的值删除后也不 难再被使用。触发器:上面

2、的触发器如果不被 disable ,则无法由序列以外的其它途 径指定代理键值,而事实上当从其它数据库复制已存在的数 据或通过后台管理工具手工输入记录的时候,我们是不希望 序列来提供值的。为了解决触发器的这一问题,可 以稍加改进,将触发器代码改为Begin if :new.idcolname is null thenSelect se_tablename_idcolname.NEXTVAL into nTmpID from dual;end if;这样,就可以在记录的代理键已指定的情况下不在由触发器 /序列提供值了。 2. 只使用触发器生成代理键上面的方法中需要为每个表创建一个对应的序列和一个对

3、 应的触发器,这显然比较麻烦,我们可以采用下面的方法进 行改进。a. 创建一个存储过程,用于计算指定表的可用键值 (如果有漏洞则返回最小的一个,否则返回最大值的下一个 值)。该过程只需要创建一个,就可以被所有表的触发器调 用。PROCEDURE SP_FINDIDHOLE( sTable INvarchar2, sIDColName IN varchar2, nIDHole Out Number, nMin IN Number:=1)IS /*function: 查找 ID 字段中的空缺数,如果没有就返回最大值 加 1. 从指定的最小值开始查找, 忽略比指定的最小值还小的 ID 值。 algo

4、rithm :对半查找法 /插值法 */l_min Number(38);l_max Number(38);actual_count Number(38);sDynSql varchar(1000);beginsDynSql:=select max(|sIDColName|),min(),count(|sIDCo lName|) From |sTable| Where>|To_Char(nMin);execute immediate sDynSql into l_max,l_min,actual_count;l_min:=nMin;expected_count := l_max - l_

5、min + 1;if expected_count = actual_count thennIDHole:=l_max+1;return;while l_max - l_min &= 1 loop- try lower half of rangehalf := trunc(expected_count/2);= expected_count - half;select count( Where between |To_Char(l_min)| and |To_Char(l_max - half); execute immediate sDynSql into actual_count;exit

6、 when actual_count = 0;if actual_count = expected_count then- missing value must be in upper halfl_min := l_min + half;elsel_max := l_max - half;end loop;=l_min;END; - Procedureb. 为表创建一个触发器Create Or Replace Trigger tg_tablename_idcolnameBefore Insert ON tablenameFor Each RowDeclare nTmpID number(10,

7、0);if :sp_FindIDHole( tablename , idcolname,:new.idcolname); 这种方法优点是:只需要为每个表创建一个触发器各个表的触发器调用同一存储过程,触发器中代码少。存储过程每次先查找表中的键值漏洞以供使用,可以减少表 中的键值漏洞,删除后的键值将被重复使用。这种方法缺点是:如果不指定键值,则只能用于使用 Insert IntoValues 进行单行插入时生成键值,如果使用了 Insert IntoSelect 插入,则会出现错误: ora-04091 表正在修改中,函 数 /过程 /触发器不能读取。这是因为 Insert Into Select

8、 执行 过程可能涉及多条记录,而每条记录引起触发器调用的存储 过程又要读取该表数据。 3. 最完善的方法上面的方法都有一定的局限性,下面的方法通用性较强,局 限小创建一个存储过程(用于查找漏洞,同上)b.创建一个存储过程(用于替换临时键值)PROCEDURE SP_SETNEWROWID( sTable INvarchar2,sIDColName IN varchar2)IS/*function:为临时标识的新行替换代理键值 */nNewID number;nMin number(10,0);nMax number(10,0);i number(10,0);Execute Immediate

9、SelectMin(),Max(lt;=-10 Into nMin,nMax;if nMin is null theni:=nMax;while i&=nMin Loopif i&=-10 thensp_FindIDHole(sTable,sIDColName,nNewID);Update Set |To_Char(nNewID)|To_Char(i);=i-1;c. 创建一个序列,用于为任意表的新增行提供 临时的键值CREATE SEQUENCE se_multiinsert_newrow_tmpid INCREMENT BY -1 START WITH -10 MINVALUE -9999

10、999999 MAXVALUE -10 CYCLE NOORDER CACHE 20d. 为每个表创建两个触发器值以标识所有新增行)se_MultiInsert_NewRow_TmpID.NEXTVAL into nTmpIDfrom dual;ii. 表触发器(用于在 Insert 语句执行 后,对每个带有临时键值的新增行依次赋予由存储过程计算 出的最终的键值)Create Or Replace Trigger tg_tablename_idcolname_AAfter Insert ON tablenameBegin sp_SetNewRowID();这种方法的优点:可以通用于所有插入记录

11、的情况。这种方法的缺点:需要为每个表创建两个触发器 触发器的执行可能使数据库性能下降(但总体消耗原本就是必须的)三 Oracle 方法说明和选择1. 方法的选择:a) 如果确认在不指定键值的情况下,只使用 InsertInto Values 向表中插入记录, 则可以对该表采用第 2 种方法。 (如果指定了键值,触发器实际上不起作用,因此可以一次 插入多条记录,例如通过导入进行插入记录)b) 如果在不指定键值的情况下,有可能使用 InsertInto Select 向表中插入记录,则应该采用第 3 种方法。c) 如果表的键值要求不能重复使用(删除的不能再重用),则应该采用第 1 种方法。如果不介意多表共用一个 序列,可以只创建一个序列以尽量减少工作量。2.方法说明 a) 以上方法中的示例代码,均默认键值为正数,因 此采用 10 以下的负数来临时标识新增行。 如果需要负数作 为键值,应对相关代码进行适当修改。主要涉及的是 sp_FindIDHole 中的查找范围的确定和排除, se_MultiInsert_NewRow_TmpID 的生成值范围。b) 以上通用的对象(如存储过程和序列)可用于多 个表,如果多个表的情况不同,可将表按情况分组,每组采 用一个方法, 使用一套通用对象。 个别的表也可以个别处理。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1