迁移后物化视图任务执行报错ORA-23404: 刷新组 "ttd"."xxxx" 不存在

本文讨论了在使用expdp & impdp迁移数据到新库后,遇到定时任务执行失败的问题。通过分析错误日志,发现新环境中物化视图缺失startwith和next子句导致无法创建刷新组,进而引发错误。解决方案包括删除新库中的物化视图并重新创建,同时删除原有的刷新任务以避免重复调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天用expdp&impdp迁移数据到另一个新库
迁移后有个定时任务执行失败如下
Errors in file /oracle/oracle/diag/rdbms/orcl/orcl1/trace/orcl1_j001_3211.trc:
ORA-12012: 自动执行作业 150812 出错
ORA-23404: 刷新组 "ttd"."xxxx" 不存在
ORA-06512: 在 "SYS.DBMS_SYS_ERROR", line 95
ORA-06512: 在 "SYS.DBMS_REFRESH", line 23
ORA-06512: 在 "SYS.DBMS_REFRESH", line 195
ORA-06512: 在 line 1
Wed Oct 22 12:08:45 2014
查询刷新组,发现新环境刷新组不存在,原来环境有
select rowner, rname, job, interval from all_refresh;
对比原来的库的物化视图和新导入库物化视图的定义发现,新导入库中物化视图少了start with 和 next 子句的话,这样就导致没有创建刷新组,由于原来的job中的刷新任务导入到新库中,所以新库在调用dbms_refresh.refresh时报错
但是可以使用exec dbms_mview.refresh('mv');进行刷新
问题解决方法:

删除新库中的物化视图,然后重新创建,同时删除job中的原来的刷新任务,因为再次创建物化视图时会重新创建job如果不删除就会有个定时任务


如下解释:
这个错误还需要从materialized view的创建开始追溯,因为如果在create materialized view语句中加入start with 和 next 子句的话,创建MV的过程中会自动创建一个job,制定定期刷新计划,例如:
create materialized view t1_mv refresh fast 
start with to_date('21-07-2009 17:15:00', 'dd-mm-yyyy hh24:mi:ss') 
  next TRUNC(SYSDATE,'HH')+375/1440
  with primary key 
    as select * from t1;
 
SQL> select job, schema_user, interval, what from all_jobs;
 
       JOB SCHEMA_USER        INTERVAL                            WHAT
---------- ------------------ ----------------------------------- ----------------------------------------------
        21 WANGXIAOQI         TRUNC(SYSDATE,'HH')+375/1440        dbms_refresh.refresh('"WANGXIAOQI"."T1_MV"');
 
SQL>
 可以看到,这个job中的执行内容是:dbms_refresh.refresh('"WANGXIAOQI"."T1_MV"'); 而不是我们普通手动刷新MV时用的 dbms_mview.refresh 。
再来研究一下dbms_refresh这个数据包,这个包是用于产生一个刷新组以方便MV一组为单位统一刷新的。而当MV被制定刷新策略的方式指定时,会自动创建一个刷新组,并将该MV添加至这个刷新组中,所以job可以使用dbms_refresh.refresh来进行刷新。可以来看一下:
 
SQL> select rowner, rname, job, interval from all_refresh where rname = 'T1_MV';
 
ROWNER               RNAME                   JOB INTERVAL
-------------------- ---------------- ---------- ----------------------------------------
WANGXIAOQI           T1_MV                    21 TRUNC(SYSDATE,'HH')+375/1440
 
    再看这个组的成员:
 
SQL> select rowner, rname, job, interval from all_refresh_children where rname = 'T1_MV';
 
ROWNER               RNAME                   JOB INTERVAL
-------------------- ---------------- ---------- ----------------------------------------
WANGXIAOQI           T1_MV                    21 TRUNC(SYSDATE,'HH')+375/1440
 
<think>嗯,我现在遇到了一个Oracle数据库的错误,错误号是ORA-00001,提示违反了唯一约束HCP.PK_DEPT_DAILY。还有一个关于触发器或者存储过程UPDATE_DEPT_DAILY在行111的报错,以及ORA-06512在第二行。我需要仔细分析这个问题,找出原因并解决它。 首先,ORA-00001表示违反了唯一性约束,也就是说试图插入或更新数据时,某个字段或字段合的值已经存在,导致重复。这里的约束是HCP模式下的PK_DEPT_DAILY,可能是一个主键约束或者唯一索引。主键通常要求唯一且非空,所以重复的主键值会导致这个错误。 接下来,错误信息指出问题发生在HCP.UPDATE_DEPT_DAILY这个对象的第111行。这可能是一个存储过程、触发器或者包中的代码。ORA-06512是调用堆栈信息,说明错误是在执行这个对象的第111行时发生的,而第二个ORA-06512可能指示调用该对象的代码位置,比如在匿名块的第二行。 我需要检查UPDATE_DEPT_DAILY的代码,尤其是第111行附近的逻辑。可能是在执行INSERT或UPDATE语句时,没有正确处理主键字段,导致重复的值被插入。比如,可能在插入前没有检查是否存在相同的主键,或者在生成主键值时出现了重复,比如使用序列但没有正确获取下一个值,或者业务逻辑生成的值有冲突。 另外,考虑主键的数据类型和生成方式。如果是自增主键,可能序列没有正确设置,或者在多会话环境下出现了问题。如果是复合主键,可能需要检查多个字段的合是否有重复的可能。 可能的解决步骤包括: 1. 确定PK_DEPT_DAILY约束的具体字段:通过查询数据字典视图,比如USER_CONSTRAINTS和USER_CONS_COLUMNS,找出涉及哪些字段。 2. 检查重复数据:根据主键字段,查询目标表HCP.DEPT_DAILY,查看是否有重复的值存在,或者即将插入的数据是否与现有数据冲突。 3. 分析UPDATE_DEPT_DAILY的代码逻辑:查看第111行附近的SQL语句,确认INSERT或UPDATE操作是否在没有适当检查的情况下试图插入重复主键。 4. 检查主键生成机制:如果主键是手动生成或依赖某些业务逻辑,可能需要确保生成的值唯一。如果是使用序列,检查是否有正确的NEXTVAL调用。 5. 处理异常:在代码中添加异常处理,捕获ORA-00001错误,并进行相应处理,比如回滚或记录日志。 6. 考虑并发问题:如果是高并发环境,可能出现同时生成相同主键的情况,需要确保序列有足够的缓存或使用其他机制避免冲突。 可能还需要在测试环境中复现问题,或者通过日志追踪具体导致重复的数据值。此外,检查是否有触发器或其他数据库对象在操作数据时间接导致主键重复。</think>### Oracle 错误 ORA-00001 分析及解决步骤 #### 错误背景 - **错误代码**:`ORA-00001: unique constraint (HCP.PK_DEPT_DAILY) violated` - **附加信息**: - `ORA-06512: at "HCP.UPDATE_DEPT_DAILY", line 111` - `ORA-06512: at line 2` #### 错误原因 此错误表示在向表 `HCP.DEPT_DAILY` 插入或更新数据时,违反了主键或唯一性约束 `PK_DEPT_DAILY`。可能的原因包括: 1. **主键重复**:试图插入或更新的数据与表中现有记录的主键值重复。 2. **代码逻辑问题**:存储过程/触发器 `HCP.UPDATE_DEPT_DAILY` 的代码(第 111 行附近)未正确处理主键生成或检查逻辑。 3. **并发冲突**:多会话同时操作导致主键生成冲突(例如序列未正确使用)。 --- #### 逐步排查及解决 ##### 1. 确认约束关联的字段 执行以下 SQL,定位 `PK_DEPT_DAILY` 约束的具体字段: ```sql SELECT column_name FROM all_cons_columns WHERE owner = 'HCP' AND constraint_name = 'PK_DEPT_DAILY' AND table_name = 'DEPT_DAILY'; ``` ##### 2. 检查重复数据 假设主键字段为 `DEPT_ID` 和 `DATE`,查询表中是否有重复值: ```sql SELECT DEPT_ID, DATE, COUNT(*) FROM HCP.DEPT_DAILY GROUP BY DEPT_ID, DATE HAVING COUNT(*) > 1; ``` ##### 3. 分析 `UPDATE_DEPT_DAILY` 的代码 检查代码第 111 行附近的逻辑(可能为以下场景): - **直接插入未去重**: ```sql INSERT INTO dept_daily (dept_id, date, ...) VALUES (v_dept_id, v_date, ...); -- 未检查主键是否已存在 ``` - **序列未正确调用**: ```sql INSERT INTO dept_daily (id, dept_id, date, ...) VALUES (seq_dept.nextval, ...); -- 若主键包含非序列字段,仍可能重复 ``` ##### 4. 验证主键生成逻辑 - **若使用序列**: ```sql SELECT seq_dept.currval FROM dual; -- 检查当前值 ALTER SEQUENCE seq_dept INCREMENT BY 100; -- 解决跳号问题(谨慎操作) ``` - **若业务生成主键**:确保逻辑在并发场景下唯一(例如时间戳+随机数可能冲突)。 ##### 5. 处理并发冲突 - 使用 `SELECT ... FOR UPDATE` 锁定资源(谨慎使用,可能影响性能)。 - 使用数据库作业调度(如 `DBMS_JOB`)串行化操作。 ##### 6. 添加异常处理 在代码中捕获错误并记录详细信息: ```sql BEGIN -- 业务逻辑(如 INSERT/UPDATE) EXCEPTION WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE('主键冲突: DEPT_ID=' || v_dept_id || ', DATE=' || v_date); ROLLBACK; END; ``` --- #### 最终解决方案 1. **短期修复**: - 在 `UPDATE_DEPT_DAILY` 中插入前检查主键是否存在: ```sql IF NOT EXISTS (SELECT 1 FROM dept_daily WHERE dept_id = v_dept_id AND date = v_date) THEN INSERT INTO dept_daily (...) VALUES (...); END IF; ``` - 或使用 `MERGE` 语句合并操作: ```sql MERGE INTO dept_daily d USING (SELECT v_dept_id AS dept_id, v_date AS date FROM dual) s ON (d.dept_id = s.dept_id AND d.date = s.date) WHEN NOT MATCHED THEN INSERT (...) VALUES (...); ``` 2. **长期优化**: - 重新设计主键生成逻辑(如复合主键包含时间戳+业务编码)。 - 增加日志记录,跟踪主键冲突的详细场景。 --- #### 注意事项 - 操作前备份数据(如导出冲突时间段的数据)。 - 在测试环境验证后再部署到生产环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值