【问题标题】:EXECUTE IMMEDIATE PL/SQL?立即执行 PL/SQL?
【发布时间】:2015-06-04 15:23:00
【问题描述】:
CREATE OR REPLACE TRIGGER P88
AFTER INSERT ON reparation    
FOR EACH ROW   

DECLARE
vope number;    
BEGIN    
  SELECT observation_reparation into vope from repartion;    
  if(vope IS NULL)THEN

  EXECUTE IMMEDIATE 'ALTER TABLE ' || reparation.observations_Reparation || ' MODIFY libelle_piece NVARCHAR2(50)';    
END IF;
END;
/

我明白了:

错误:表或​​视图不存在。

【问题讨论】:

  • 我知道您混淆了模式名称、表名称和列名称。触发器在 REPARATION 上,您选择列 OBSERVATION_REPARATION 并从模式 REPARATION 中截断表 OBSERVATIONS_REPARATION。您实际要截断哪个表以及它在什么架构中?
  • @davegreen100 如果未指定observations_Réparation 字段,我想这样做,触发器将自动在其位置插入libelle_piece
  • 好的,我明白了,但是您要修改哪个表?真的是reparation.observations_Reparation
  • @davegreen100 名称表是修复我想使用立即执行修改列 observation_Reparation 为 libelle_piece
  • 您能备份并解释您要解决的问题吗?为什么要从触发器发出 DDL?从技术上讲,这是行不通的。 DDL 语句隐式结束事务,并且不允许触发器结束事务,因此不允许触发器执行 DDL。通常,不允许从该表查询表上的行级触发器,因此您的 SELECT 可能会生成变异表异常。在您要插入的表上执行 DDL 似乎从根本上被误导了。

标签: sql oracle plsql oracle11g


【解决方案1】:
CREATE OR REPLACE TRIGGER P88
AFTER INSERT ON reparation
FOR EACH ROW
DECLARE
vope number;

BEGIN

  SELECT observation_reparation into vope from repartion;

  if(vope IS NULL)THEN

    EXECUTE IMMEDIATE 'ALTER TABLE reparation RENAME COLUMN observations_Reparation TO libelle_piece';

  END IF;
END;

如果您还需要更改列的声明,则需要另一个 ALTER 语句

alter table reparation modify (libelle_piece NVARCHAR2(50))

【讨论】:

  • 就像 EXECUTE IMMEDIATE 'reparation modify (libelle_piece NVARCHAR2(50))' ? @davegreen100
  • 立即执行'alter table reparation modify (libelle_piece NVARCHAR2(50))';
  • 如果你真的导致了触发器的执行,你会得到一个错误。 DDL 隐式提交,但不允许触发器结束事务。所以你不能在触发器中做 DDL。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 2023-03-31
  • 2018-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多