修改表A的某字段时将此字段内容传入表B修改对应字段内容的触发器写法

ORA-04091:表发生了变化触发器/函数不能读

 

create or replace trigger "TRIG_ONMODY_T_SUPERVISION_MX"
   after update on t_supervision_mx
   referencing old as o
   for each row
 declare
   sxfl VARCHAR2(64);
   PRAGMA AUTONOMOUS_TRANSACTION;
 begin
   if :o.mxtype='task' then
     select ab.status
           into sxfl
           from t_supervision_mx ab
          where ab.taskid = :o.taskid;
     if sxfl='申请撤销' then
        update t_supervisiontask a set a.taskstatus= 15  where a.id = :o.taskid;
        update t_supervisiontaskfeetback b set b.feetbackcontent= :o.faNKUIQINGKUANG where b.taskid= :o.taskid;
     end if;
     if sxfl='申请完成' then
        update t_supervisiontask a set a.taskstatus= 10  where a.id = :o.taskid;
        update t_supervisiontaskfeetback b set b.feetbackcontent= :o.faNKUIQINGKUANG where b.taskid= :o.taskid;
     end if;
    end if;
 commit;
 end TRIG_ONMODY_T_SUPERVISION_MX;
  

注意添加自治事务,否则将会出现

ORA-04091:表发生了变化触发器/函数不能读

的错误

<think>好的,用户现在需要编写一个Informix的SPL存储过程,从一个读取数据,然后根据这些数据在另一个中删除。首先,我需要回顾之前关于触发器的回答,确保这次的存储过程写法符合Informix的语法规则。 用户之前的提问是关于触发器如何执行多条SQL,现在转向存储过程,这可能意味着他们希望将数据处理的逻辑封装起来,可能在触发器或其他地方调用。需要确认存储过程的结构,包括参数、变量声明、游标使用以及异常处理。 首先,存储过程的基本结构应该是CREATE PROCEDURE,可能需要输入参数,比如源的某个字段值,用来指定要读取的数据。然后,使用游标或者SELECT INTO语句来获取数据。不过,如果处理多行数据,游标更合适,因为SELECT INTO只能处理单行。 接下来,需要考虑如何循环游标中的数据,并用这些数据执行删除操作。在Informix中,使用FOREACH循环来处理游标会更方便。同,异常处理也很重要,需要包括ON EXCEPTION语句来捕获错误,比如数据不存在或外键约束问题。 另外,用户可能需要事务控制,确保读取和删除操作的原子性。不过,在Informix中,存储过程默认是否在事务中执行?需要确认是否需要显式使用BEGIN WORK和COMMIT或ROLLBACK。 权限也是一个问题,用户需要有源和目标的SELECT和DELETE权限,否则存储过程会执行失败。此外,是否应该使用动态SQL?如果名或条件需要动态传入,可能需要使用EXECUTE IMMEDIATE,但根据用户的问题描述,似乎结构是固定的,所以静态SQL即可。 可能的错误点包括:游标未正确关闭,变量未初始化,或者WHERE条件不正确导致删除过多或过少的数据。需要示例中的变量名和名是否清晰,比如使用src_table和target_table,或者具体的例子如orders和order_details。 此外,用户可能需要一个具体的示例,比如从orders读取order_id,然后删除order_details对应的记录。这样示例更具体,用户更容易理解。 最后,注意事项部分需要提到性能问题,比如如果源数据量大,使用游标可能效率低,可以考虑批量处理或直接使用子查询删除。但根据用户需求,可能必须逐行处理,比如有额外的逻辑需要在删除前处理每条记录。 总结步骤:创建存储过程,声明变量,定义游标,循环处理每条记录,执行删除,异常处理,结束过程。同,提供调用示例和注意事项,比如权限、事务、性能等。</think>在 Informix 中编写存储过程(SPL)实现 **跨读取数据并删除** 的步骤如下,需使用 **游标(CURSOR)** 逐行处理数据: --- ### 示例场景 假设有两个: - **`source_table`**(源):存储需要读取的数据(如 `id`, `filter_key`) - **`target_table`**(目标):根据源数据删除记录 --- ### 存储过程代码 ```sql CREATE PROCEDURE delete_based_on_source() -- 定义变量(与源字段类型匹配) DEFINE v_id INT; DEFINE v_filter_key VARCHAR(50); -- 定义异常处理 ON EXCEPTION -- 可选:记录错误信息(需有日志) INSERT INTO error_log (error_message) VALUES (SQLERRM); RAISE EXCEPTION -746, 'Delete operation failed'; END EXCEPTION; -- 打开游标读取源数据 FOREACH cursor_source WITH HOLD FOR SELECT id, filter_key FROM source_table WHERE condition = 'your_criteria' -- 替换为实际条件 INTO v_id, v_filter_key -- 根据读取的数据删除目标记录 DELETE FROM target_table WHERE target_id = v_id -- 假设目标字段为 target_id AND target_key = v_filter_key; -- 可选:添加其他逻辑(如记录删除日志) INSERT INTO delete_log (deleted_id) VALUES (v_id); END FOREACH; -- 结束游标循环 -- 关闭游标(Informix 自动处理,但显式关闭更规范) CLOSE cursor_source; END PROCEDURE; ``` --- ### 关键步骤解析 1. **游标声明**: - 使用 `FOREACH` 逐行读取 `source_table` 的数据。 - `WITH HOLD` 确保游标在事务提交后仍保持打开(需根据事务需求调整)。 2. **变量定义**: - `DEFINE` 声明变量,类型需与源字段匹配。 3. **删除操作**: - 通过 `DELETE` 语句,用游标读取的变量值 (`v_id`, `v_filter_key`) 定位目标记录。 4. **异常处理**: - `ON EXCEPTION` 捕获错误,可记录到日志并抛出异常终止操作。 --- ### 调用存储过程 ```sql EXECUTE PROCEDURE delete_based_on_source(); ``` --- ### 注意事项 1. **权限**:执行用户需对 `source_table` 有 `SELECT` 权限,对 `target_table` 有 `DELETE` 权限。 2. **事务控制**: - 默认情况下,存储过程内的操作在事务中执行,失败自动回滚。 - 若需手动控制,可添加 `BEGIN WORK` 和 `COMMIT/ROLLBACK`。 3. **性能优化**: - 若数据量大,避免逐行删除,改用批量操作(如直接 `DELETE ... WHERE EXISTS`)。 - 示例中游标逐行处理适合需要逐行校验或记录日志的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值