ORACLE在Execute Immediate中批处理DDL语句

时间:2009-08-06 21:30:30

标签: sql oracle oracle10g ora-00911

我正在尝试在一个Execute Immediate语句中运行多个ddl语句。 我认为这将是非常直接的,但似乎我错了。

这个想法是这样的:

declare v_cnt number; 

begin 

select count(*) into v_cnt from all_tables where table_name='TABLE1' and owner = 'AMS'; 

if v_cnt = 0 then 

execute immediate 'CREATE TABLE TABLE1(VALUE VARCHAR2(50) NOT NULL)  ALTER TABLE TABLE1 ADD (MYVAL2 NVARCHAR2(10))'; 

end if; 

end;

然而这会导致错误

  

ORA-00911:无效字符   ORA-06512:第10行

如果我自己执行它们,批处理中的每个语句都可以正常运行。如果我接受这个语句并执行它,它将运行良好(使用;在两个语句之间)。如果我删除;在语句之间我得到关于无效选项的不同错误

计划是我将能够构建一个表,导出该表的表模式,包括它的所有alter语句,然后作为安装/更新过程的一部分在另一个系统上运行批处理。

那么,我如何在单个执行立即批处理中批处理这些DDL语句?或者有更好的方法来做我需要的东西吗?

我必须承认,我有点像Oracle新手。谢谢大家的耐心等待。

2 个答案:

答案 0 :(得分:4)

分号不是Oracle SQL语法的一部分。 SQL * Plus和其他客户端工具使用分号来表示SQL语句的结束,但服务器没有看到它。

我们可以强制SQL * Plus将分号传递给DB:

SQL> set sqlterminator off
SQL> select * from user_tables;
  2  /
select * from user_tables;
                         *
ERROR at line 1:
ORA-00911: invalid character

如果我接受此语句并执行它,它将运行良好(使用;在两个语句之间)您正在使用的客户端工具,将其分成两次调用DB。

因此,我认为不可能在执行立即数内传递多个语句。

我想可以使用包含匿名PL / SQL块的字符串调用execute immediate,并且单独调用在其中立即执行...而且我不知道这样做的重点是什么。 ;)

答案 1 :(得分:2)

为什么需要单个EXECUTE IMMEDIATE调用?当然只是做2个电话?

请记住,每个DDL语句都包含一个隐式COMMIT,因此作为单个调用执行此操作不会产生任何可靠性。

另外,为什么不在第一次通话中正确设置表格呢?你可以做......

CREATE TABLE TABLE1(VALUE VARCHAR2(50)NOT NULL,MYVAL2 NVARCHAR2(10))

...而不是需要2个电话。

另外,你看过DBMS_METADATA ......它可以为你的表格等对象生成DDL。