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 语句的主要内容,如果未能解决你的问题,请参考以下文章