5

我试图在一个 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 新手。谢谢大家的耐心。

4

2 回答 2

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

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

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

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

于 2009-08-06T22:24:35.893 回答
2

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

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

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

创建表 TABLE1(值 VARCHAR2(50)不为空,MYVAL2 NVARCHAR2(10))

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

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

于 2009-08-06T21:33:38.037 回答