Tag Archives: TRIGGER

ORA-600(kglobpn-bad-pga)错误

这个错误比较罕见,无论是GOOGLE还是METALINK都找不到任何的相关信息。 数据库版本是11.2.0.2 RAC环境,这个错误之所以这么罕见,也和11.2的版本太新,以致于很多问题都还没有暴露出来有关。 错误信息为: 2012-03-29 04:06:02.353000 +08:00 Errors IN file /oracle/diag/rdbms/orcl/orcl1/trace/orcl1_ora_18355.trc (incident=144401): ORA-00600: internal error code, arguments: [kglobpn-bad-pga], [], [], [], [], [], [], [], [], [], [], [] Incident details IN: /oracle/diag/rdbms/orcl/orcl1/incident/incdir_144401/orcl1_ora_18355_i144401.trc 2012-03-29 04:10:12.017000 +08:00 Dumping diagnostic DATA IN … Continue reading

Posted in BUG | Tagged , , , | Leave a comment

利用触发器解决更新主键冲突的问题

有朋友问我能否用触发器实现更新数据时,如果发现主键已经存在,则将冲突的主键更新为当前记录之前的主键值。 简单的说,如果表中存在主键为1和2的记录,如果一条UPDATE语句将1更新为2,那么想要实现的功能是为了确保这个UPDATE可以执行成功,在后台自动将ID为2的记录更新为1。 这个功能应该可以实现,但是直接在触发器中肯定无法实现,因为这是一个标准的变异表问题。而且即使是采用自治事务的方式,也需要小心,因为要修改原有的记录就必须通过UPDATE实现,而这个UPDATE又会导致触发器的触发,如果处理不当,就会导致循环触发。 SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30), CONSTRAINT PK_T PRIMARY KEY (ID)); TABLE created. SQL> CREATE OR REPLACE PROCEDURE P_UPDATE_T (P_NEW NUMBER, P_OLD NUMBER) AS 2 BEGIN 3 FOR I IN (SELECT ID FROM T WHERE … Continue reading

Posted in ORACLE | Tagged , , , , | Leave a comment

默认值和触发器的顺序

今天在写触发器的时候突然想到这一点,为了验证想法,做了一个简单的例子。 如果一个字段拥有默认值,且包含一个BEFORE的行级触发器,当不指定值时,二者的生效顺序如何: SQL> CREATE TABLE t_trigger_default (id NUMBER, col varchar2(30) DEFAULT ‘default’); TABLE created. SQL> CREATE TRIGGER t_b_tri_def 2 BEFORE INSERT ON t_trigger_default 3 FOR each ROW 4 BEGIN 5 :NEW.col := ‘trigger’; 6 END; 7 / TRIGGER created. SQL> … Continue reading

Posted in ORACLE | Tagged , , | Leave a comment

快速增加表的默认值的方法

看到ITPUB上有人提到,如何快速的在一个3亿条记录的表中增加一个包含DEFAULT值的新字段。描述一下如何快速的添加表的默认值。 Oracle11新特性——在线操作功能增强(二) :http://yangtingkun.itpub.net/post/468/401293 对于这个问题,常规的方法有三个: 一、直接ALTER TABLE ADD COLUMN,这种方法的好处是简单,一个命令就可以完成,缺点是耗时非常长,而且在漫长的执行过长中都会锁定表,导致应用无法修改数据,并且在完成后容易造成大量的行迁移,从而影响后续访问的性能; 二、CREATE TABLE AS SELECT的方式,这种方式相对第一种而言,效率更高,如果是非归档模式,那么完成速度会更快。但是缺点同样很明显,首先需要大量的停机时间,而且表上的索引、约束、触发器以及权限等都需要手工处理,比较麻烦; 三、在线重定义,这种方式应该算是这三种中最佳的,锁表时间非常短,对业务影响最小,但是缺点是整个操作的时间并不会变短,和第二种方式一样,都需要2倍的存储空间,而且操作相对复杂。 如果数据库的版本是11g,那么这就不是问题了,以前写过专门的文章,描述11g是如何快速添加一个包含非空DEFAULT值的列的。那么对于10g及以前版本的数据库而言,增加一个包含默认值的字段难道就真的要忍受漫长的执行时间和大量的REDO、UNDO的占用吗。 其实完全可以仿照11g的方式,来自己实现10g中字段的快速添加。记得Tom在描述数据库的解析时提到过,软解析要优于硬解析,软软解析要优于软解析,而速度最快的莫过于不解析。提高速度的最高境界就是根本不做。 那么对于添加默认值的方式也可以才有这种方法,对于已经存在的记录的默认值,我们根本不去添加,一个简单的例子如下: SQL> CREATE TABLE T_ADD_COLUMN (ID NUMBER, NAME VARCHAR2(30)); TABLE created. SQL> INSERT INTO T_ADD_COLUMN 2 SELECT ROWNUM, OBJECT_NAME 3 FROM DBA_OBJECTS; 11955 ROWS created. … Continue reading

Posted in ORACLE | Tagged , , , , | Leave a comment

DDL触发器设置导致DDL无法执行(二)

公司测试数据库发现执行DDL报错。 继续描述问题的诊断和解决。 DDL触发器设置导致DDL无法执行(一):http://yangtingkun.itpub.net/post/468/526410 从对象定义是找不到问题的原因的,只能通过10046跟踪一下: SQL> ALTER SESSION SET EVENTS ‘10046 TRACE NAME CONTEXT FOREVER, LEVEL 12’; Session altered. SQL> CREATE TABLE T_CREATE (ID NUMBER); CREATE TABLE T_CREATE (ID NUMBER) * ERROR at line 1: ORA-00604: error occurred at recursive SQL … Continue reading

Posted in ORACLE | Tagged , , , | Leave a comment

DDL触发器设置导致DDL无法执行(一)

公司测试数据库发现执行DDL报错。 由于篇幅所限,这里简单描述一下问题产生的现象。 打算进行个测试,结果发现建表时报错: SQL> CREATE TABLE T_EXCHANGE (ID NUMBER, CREATED DATE, TYPE VARCHAR2(18)) 2 PARTITION BY RANGE (CREATED) SUBPARTITION BY LIST (TYPE) 3 (PARTITION P1 VALUES LESS THAN (TO_DATE(’2012-1′, ‘YYYY-MM’)) 4 (SUBPARTITION P1SP1 VALUES (’TABLE’), 5 SUBPARTITION P1SP2 VALUES (’INDEX’), … Continue reading

Posted in ORACLE | Tagged , , , , | Leave a comment