注册
达梦数据库-错误码-[-2068]-分析处理
技术分享/ 文章详情 /

达梦数据库-错误码-[-2068]-分析处理

PYZ 2024/08/23 585 0 0

错误码:-2068
错误内容:在参数ENABLE_TMP_TAB_ROLLBACK为0或STANDBY模式下,不支持对包含唯一索引的临时表进行增删改操作

示例:

1、在主备环境下,构造测试用例

--创建表 create table t1(id number,name varchar2(20),constraint PK_T1_ID not cluster primary key (ID)); create global temporary table TMP_T1(ID number,NAME varchar2(128),constraint PK_TMPT1_ID not cluster primary key (ID)); --插入数据 insert into t1 values (1,'TONY'); insert into t1 values (2,'STEVE'); commit; --创建包,其中函数实现查询返回结果,存储过程实现将数据插入临时表进行处理 create or replace package pkg_test_1 as function f_getname(vid number) return varchar2; procedure p_inst(vid number); end; / create or replace package body pkg_test_1 as function f_getname(vid number) return varchar2 as res_name varchar2(20); begin select name into res_name from T1 where id=vid; return res_name; end; procedure p_inst(vid number) as begin insert into TMP_T1 select * from t1 where id=vid; end; end; /

2、当备库执行调用包里的函数时会出现-2068报错

[执行语句1]: select pkg_test_1.f_getname(1) from dual; 执行失败(语句1) -3325: 第14 行附近出现错误[-2068]:在参数ENABLE_TMP_TAB_ROLLBACK为0或STANDBY模式下,不支持对包含唯一索引的临时表进行增删改操作

问题点:

包里存在两个方法,函数为查询操作,存储过程为DML操作,备库只读正常应该允许执行查询,而问题场景中即使没有直接调用包里的存储过程,结果还是会出现报错。

问题原因:

1、DM对于PL/SQL代码块会先获取所有语句的计划,在调用包时存储过程中的DML语句也需要进行解析,因此在备库模式下执行查询操作也会报错;
2、ENABLE_TMP_TAB_ROLLBACK默认为1,表示临时表操作是否生成回滚记录,0:不生成;1:生成。置为0时,有三项限制:
一是临时表的 DML 操作无法回滚;
二是不允许对包含唯一索引的临时表进行增删改操作;
三是不允许对临时表创建唯一索引、主键约束和唯一约束;
因此当ENABLE_TMP_TAB_ROLLBACK=0的情况下,无论主库还是备库都会出现相关报错。

问题处理:

1、可以将存储过程中的语句改写为动态执行,可以避免存储过程中的语句被提前解析;

procedure p_inst(vid number) as begin execute immediate 'insert into TMP_T1 select * from t1 where id='||vid; --insert into TMP_T1 select * from t1 where id=vid; end;

2、当临时表中不存在主键或唯一索引的情况下,也可以避免-2068报错,但删除唯一约束可能会改变应用程序的业务逻辑;

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服