ORACLE 在立即执行中批处理 DDL 语句

Posted

技术标签:

【中文标题】ORACLE 在立即执行中批处理 DDL 语句【英文标题】:ORACLE Batching DDL statements within a Execute Immediate 【发布时间】:2009-08-06 21:30:29 【问题描述】:

我试图在一个 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 行

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

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

那么,我如何在单个执行立即数中批处理这些 DDL 语句?还是有更好的方法来做我需要的事情?

我必须承认,我是一个 Oracle 新手。谢谢大家的耐心。

【问题讨论】:

【参考方案1】:

分号不是 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

如果我使用这条语句并执行它,它将运行良好(在 2 条语句之间使用 ;)您正在使用的客户端工具将它分成两个对数据库的调用。 p>

所以,我认为不可能在执行立即数中传递多个语句。

我想可以使用包含匿名 PL/SQL 块的字符串调用 execute immediate,并在其中单独调用 execute immediate ...我不知道这样做的意义何在。 ;)

【讨论】:

我的经验是一样的:我们不能在EXECUTE IMMEDIATE中传递多个语句。【参考方案2】:

为什么需要一个 EXECUTE IMMEDIATE 调用?肯定只做 2 个电话吗?

请记住,每个 DDL 语句都包含一个隐式 COMMIT,因此作为单个调用执行它没有并发优势。

另外,为什么不在第一次通话中正确设置桌子?你可以...

创建表 TABLE1(VALUE VARCHAR2(50) NOT NULL, MYVAL2 NVARCHAR2(10))

...而不是需要 2 次调用。

另外,您是否查看过 DBMS_METADATA... 它可以为您生成表等对象的 DDL。

【讨论】:

表创建和更改被导出为单个文件,现在,它们已经足够多,值得尝试在 1 EXECUTE IMMEDIATE 中尝试执行此操作而不是每个 db 对象执行很多操作。 在这种情况下,我建议首先生成正确的 DDL。查看 DBMS_METADATA。 :-) 看起来这可以解决我的问题。可悲的是,显而易见的答案就在我的眼皮底下。经验教训:即使有精美的 gui 菜单,也不要使用 TOAD 来输出结构。 实际上是两个隐式提交。一个在开头,一个在结尾。

以上是关于ORACLE 在立即执行中批处理 DDL 语句的主要内容,如果未能解决你的问题,请参考以下文章

如何使用sqlcmd在批处理脚本中执行SQL?

oracle中DDL DML指啥?

oracle中DDL DML指啥?

怎么用批处理*.bat 执行文件目录下面的SQL语句脚本(批量的)

自治事务中的 Oracle DDL

oracle ddl语句用啥编辑