【问题标题】:error in EXECUTE IMMEDIATE insert ORACLEEXECUTE IMMEDIATE 插入 ORACLE 中的错误
【发布时间】:2014-06-03 02:09:27
【问题描述】:

晚安。 我对 Oracle 中的 EXECUTE IMMEDIATE 有疑问。 我查看其他主题,但没有任何答案有帮助。 这是代码: 首先,我需要在触发器内插入的表...

create global temporary table TEMP_PK (COL_NAME VARCHAR(100), COL_TYPE VARCHAR(100), ROW_VALUE VARCHAR(100)) on commit preserve rows;

现在,我的触发器

CREATE OR REPLACE TRIGGER ICidade AFTER
  INSERT ON Cidade FOR EACH ROW DECLARE TYPE EmpCurTyp IS REF CURSOR;
  emp_cv EmpCurTyp;
  col_name_aux VARCHAR(100);
  col_type_aux VARCHAR(100);
  stm          VARCHAR(4000):='';
  BEGIN
    -- Pegando as PKS
    FOR j IN
    (SELECT d.Column_Name coluna,
        d.DATA_TYPE tipo
      FROM user_cons_columns ucc,
        user_constraints uc,
        (SELECT COLUMN_NAME,DATA_TYPE FROM ALL_TAB_COLUMNS WHERE TABLE_NAME='CIDADE'
        ) d
      WHERE uc.constraint_name=ucc.constraint_name
      AND uc.constraint_type  ='P'
      AND uc.table_name       = 'CIDADE'
      AND d.COLUMN_NAME       =ucc.Column_Name
    )
    LOOP
      stm := concat
      (
        stm, 'INSERT INTO TEMP_PK VALUES ('
      )
      ;
      stm := concat(stm, j.coluna);
      stm := concat(stm,', ');
      stm := concat(stm, j.tipo);
      stm := concat(stm,', ');
      stm := concat(stm, ':NEW.');
      stm := concat(stm,j.coluna);
      stm := concat(stm,')');

      EXECUTE IMMEDIATE stm;
      stm:='';
    END LOOP;


  END ICidade;
  /

编译良好。问题是当我在“Cidade”表中添加一个条目时 当我尝试插入时,例如:

Insert into Cidade Values (11,'Alegre','ES');

当我在没有立即执行的情况下运行时,使用打印功能,结果如下:

插入 TEMP_PK 值(CODCIDADE、NUMBER、:NEW.CODCIDADE);

使用 EXECUTE IMMEDIATE,会出现以下错误:

从第 62 行开始的错误命令 - 插入 Cidade VALues (11,'Alegre','ES') 错误报告 - SQL 错误: ORA-00936: 缺失 表达式 ORA-06512:在“PAULA.ICIDADE”,第 34 行 ORA-04088:错误 在执行触发器“PAULA.ICIDADE”期间 00936. 00000 - “缺少表达式”

可能是一个白痴错误,但我找不到。

那么谁能帮助我?从现在开始,谢谢你。

【问题讨论】:

  • 如果您将 SELECT 语句从触发器中拉出并在 SQL*Plus 等查询工具中运行,它是否会返回您期望的列名和值?
  • 是的,通常插入@bob-jarvis
  • 如果您必须使用动态 INSERT 填充 TEMP_PK,这将非常棘手。通常主键的定义不会更改这么多次,因此静态 INSERT 可能就足够了。您应该考虑编写一个专用的 INSERT-Procedure 来完成所有操作,而不是使用触发器。

标签: sql oracle execute-immediate


【解决方案1】:

我建议你在执行之前使用 DBMS_OUTPUT.PUT_LINE 输出stm。这样可以更轻松地查看您正在运行的内容以及生成错误 SQL 的原因。

首先,您没有将任何内容绑定到:NEW

【讨论】:

  • 所以我已经看到了输出,之前正在打印。我只是在这里发帖我的问题是':new',因为我需要根据表名获取它的值,你知道我该怎么做吗?
【解决方案2】:

看起来您需要在插入到 COL_NAME 和 COL_TYPE 列中的字符串文字周围加上单引号。尝试将触发器重写为:

CREATE OR REPLACE TRIGGER ICidade AFTER
  INSERT ON Cidade FOR EACH ROW DECLARE TYPE EmpCurTyp IS REF CURSOR;
  emp_cv EmpCurTyp;
  col_name_aux VARCHAR(100);
  col_type_aux VARCHAR(100);
  stm          VARCHAR(4000):='';
  BEGIN
    -- Pegando as PKS
    FOR j IN
    (SELECT d.Column_Name coluna,
        d.DATA_TYPE tipo
      FROM user_cons_columns ucc,
        user_constraints uc,
        (SELECT COLUMN_NAME,DATA_TYPE FROM ALL_TAB_COLUMNS WHERE TABLE_NAME='CIDADE'
        ) d
      WHERE uc.constraint_name=ucc.constraint_name
      AND uc.constraint_type  ='P'
      AND uc.table_name       = 'CIDADE'
      AND d.COLUMN_NAME       =ucc.Column_Name
    )
    LOOP
      stm := 'INSERT INTO TEMP_PK (COL_NAME, COL_TYPE, ROW_VALUE) ' ||
             'VALUES (''' || j.coluna || ''', ' ||
                      '''' || j.tipo || ''', ' ||
                      ':NEW.' || j.coluna || ')';

      EXECUTE IMMEDIATE stm;
    END LOOP;
  END ICidade;

分享和享受。

【讨论】:

  • 谢谢。此错误已解决 rs 另一个出现 * 悲伤 *,给出了“并非所有变量都绑定”。但现在我会尝试解决。再次感谢您。
  • 问题是触发器内部的“:NEW”这样的术语用于列的新值,但也用于动态SQL中的绑定变量。我认为没有任何解决方案可以在触发器中同时使用两者。
猜你喜欢
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 2015-10-07
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 2021-04-15
相关资源
最近更新 更多