Oracle有一个名为timestamp的字段,为什么创建触发器会失败?

时间:2008-11-12 17:13:04

标签: sql oracle ora-06553

我只是浪费了我生命中的最后两个小时试图在this tutorial创建一个自动递增主键基础的表格,教程很棒我遇到的问题是创建目标如果我有一个时间戳列和一个在同一个表中称为时间戳的表,则会失败...

为什么oracle在创建表时没有将此标记为问题?

这是我输入的命令序列:

  1. 创建表格:

    CREATE TABLE myTable
       (id NUMBER PRIMARY KEY,
        field1 TIMESTAMP(6),
        timeStamp NUMBER,
    );
    
  2. 创建序列:

    CREATE SEQUENCE test_sequence
    START WITH 1
    INCREMENT BY 1;
    
  3. 创建触发器:

    CREATE OR REPLACE TRIGGER test_trigger  
    BEFORE INSERT  
    ON myTable  
    REFERENCING NEW AS NEW  
    FOR EACH ROW  
    BEGIN  
    SELECT test_sequence.nextval INTO :NEW.ID FROM dual;  
    END;  
    /
    
  4. 以下是我收到的错误消息:

    ORA-06552: PL/SQL: Compilation unit analysis terminated
    ORA-06553: PLS-320: the declaration of the type of this expression is incomplete or malformed
    

    没有两行中带有“timestamp”一词的任何组合都可以正常工作。我原以为语法足以区分关键字和列名。

    正如我所说,我不明白为什么表格被创建好但是当我尝试创建触发器时oracle会崩溃......

    澄清

    我知道问题是有一个名为timestamp的列可能是也可能不是关键字。我的问题是为什么当我试图创建一个触发器而不是我创建表时它会被禁止,我至少会预期会发出警告。

    那说使用Oracle几个小时,它的错误报告似乎不那么冗长,也许只是因为我使用的是快递版本。

    如果这是Oracle中的一个错误,那么没有支持合同的人会如何报告?我只是在使用快速版本,因为我必须将一些代码从MySQL迁移到Oracle。

6 个答案:

答案 0 :(得分:9)

关于这个(227615.1)摘录的metalink上有一个注释:

# symptom: Creating Trigger fails
# symptom: Compiling a procedure fails
# symptom: ORA-06552: PL/SQL: %s
# symptom: ORA-06553: PLS-%s: %s     
# symptom: PLS-320: the declaration of the type of this expression is incomplete or malformed
    # cause: One of the tables being references was created with a column name that is one of the datatypes (reserved key word). Even though the field is not referenced in the PL/SQL SQL statements, this error will still be produced.

    fix:

    Workaround:

    1. Rename the column to a non-reserved word.
    2. Create a view and alias the column to a different name.

答案 1 :(得分:3)

TIMESTAMP未在Oracle文档中列为保留字(这很令人惊讶)。

它列在V $ RESERVED_WORDS数据字典视图中,但其RESERVED标志设置为'N'。

这可能是触发器处理中的错误。我想说这对Oracle支持来说是个好消息。

答案 2 :(得分:1)

你自己暗示了答案。您使用timestamp作为列名,但它也是一个关键字。将列名更改为其他名称(例如xtimestamp)并触发编译。

答案 3 :(得分:0)

好吧,我对此并不完全确定,但我认为这是因为用于操作和访问数据库对象的SQL代码由一些解释器解释,这些解释器与用于解释PL / SQL代码的解释器不同。

请记住,SQL和PL / SQL是不同的东西,所以它们的处理方式不同。所以,我认为在一个解释器中有一些错误,只是不确定是哪一个。

答案 4 :(得分:0)

不要让Oracle维护一个视图,而是使用EXECUTE IMMEDIATE(即如果'将列重命名为非保留字'不是一个选项。

答案 5 :(得分:0)

您可以通过EXECUTE IMMEDIATE执行。这不是更好的方式,而是工作并避免列重命名。

在我的情况下,重命名列将是一种caotic方式