2012-07-02 29 views
0

在Oracle PL/SQL中,我有这种编码,它给了我编译器错误。我不知道为什么,看起来像我拥有一切......Oracle PL/SQL如何找到这个语法错误?

请帮忙。

感谢

ORA-06550: line 6, column 5: 
PLS-00103: Encountered the symbol "CREATE" when expecting one of the following: 

    (begin case declare end exit for goto if loop mod null 
    pragma raise return select update while with <an identifier> 
    <a double-quoted delimited-identifier> <a bind variable> << 
    continue close current delete fetch lock insert open rollback 
    savepoint set sql execute commit forall merge pipe purge 
06550. 00000 - "line %s, column %s:\n%s" 
*Cause: Usually a PL/SQL compilation error. 
*Action: 

代码是

begin 
    for c in (select id from tmp_A) 
    loop 
    dbms_output.put_line(c.id); 

    create table tmp_c as 
    select B.name from tmp_B B where B.id = c.id; 

    drop table tmp_c; 
    end loop; 
end; 
/
+2

为什么要在运行时创建一个表?在Oracle中这是非常罕见的,因为这是必要的,绝大多数人都是这样写代码的,这是一个错误。 –

+0

我有一个复杂的相关子查询,我想把它分成易于理解的小块。 – user595234

+1

这似乎不是在运行时创建表的合理理由。诉诸动态SQL不会让你的代码更易于理解。它会阻止多个会话成功调用相同的代码(动态创建的表对所有会话都立即可见)。有可能,您可能希望在您的过程之外创建一个全局临时表,然后在代码中插入该临时表中,但即使这种情况非常不寻常。如果您想将代码分成易于理解的部分,请使用模块化功能和过程。 –

回答

3

你不能叫DDL statments直接(CREATE,DROP,ALTER等)在PL/SQL。 你可以,但是使用立即执行的语句:

begin 
    EXECUTE IMMEDIATE 'CREATE TABLE MYTABLE(DT DATE)'; 
end; 

参见:

http://www.orafaq.com/wiki/PL/SQL_FAQ#Can_one_call_DDL_statements_from_PL.2FSQL.3F 
+0

谢谢。你是对的。你知道为什么吗 ? – user595234

+0

@ user595234 - 因为您不应该动态创建对象。如果有些用例将对象创建为普通代码路径的一部分是有意义的,那么Oracle可能会投入时间使其更容易,而不是每次引用动态对象时都强迫您使用动态SQL。但是,由于实际上并没有这种用例,所以增加复杂性使其变得非常简单并不值得。 –

+0

下面是一个答案:http://www.toadworld.com/Blogs/tabid/67/EntryId/549/Why-cant-I-execute-DDL-natively-in-PL-SQL.aspx – DCookie