如何在 oracle 中有条件地执行 DDL?
Posted
技术标签:
【中文标题】如何在 oracle 中有条件地执行 DDL?【英文标题】:How to execute DDLs conditionally in oracle? 【发布时间】:2014-04-03 16:36:13 【问题描述】:我有一个创建大量表、索引、触发器等的脚本。我想有条件地运行所有这些 DDL。我试图用 'if then' 包装脚本,但它不起作用
IF exists (select 1 from xxx where yyy) THEN
create table...
create table...
CREATE UNIQUE INDEX ...
CREATE TRIGGER ...
END IF;
我怎样才能做到这一点?
【问题讨论】:
【参考方案1】:其中一种方式:
begin
for cur in (select 1 from xxx where yyy and rownum <= 1) loop
execute immediate 'create table...';
execute immediate 'create table...';
execute immediate 'create unique index...';
end loop;
end;
/
附:另一种方法是生成异常并在 SQL*Plus 中继续。
文件example.sql:
SET ECHO OFF
SET VERIFY OFF
WHENEVER SQLERROR EXIT;
VAR x NUMBER
EXEC :x := &1
BEGIN
FOR cur IN (SELECT 1 FROM dual WHERE 1=:x) LOOP
RETURN;
END LOOP;
RAISE NO_DATA_FOUND;
END;
/
PROMPT Here we are
结果:
SQL> @example
Enter value for 1 1: 1
PL/SQL procedure completed.
PL/SQL procedure completed.
Here we are
SQL> @example
Enter value for 1: 2
PL/SQL procedure completed.
BEGIN
*
error in line 1:
ORA-01403: no data found
ORA-06512: in line 5
当我使用值 2 时,块引发异常并且脚本存在 SQL*Plus。
附:再举一个例子——希望这能解决下面的问题。我仅在表不存在时创建表。表在 DEFAULT 语句中包含 1024 个分区和 ' 字符。文字大小 > 32K。
SQL> set serveroutput on
SQL> DECLARE
2 sql_code clob;
3 delim varchar2(1) := '';
4 amount int;
5 sql_text varchar2(32767);
6 BEGIN
7
8 dbms_lob.createtemporary(sql_code,cache => true);
9 sql_text := q'[CREATE TABLE TEST_TAB (X INT PRIMARY KEY, Y VARCHAR2(10) DEFAULT 'DEF', Z INTEGER) PARTITION BY RANGE(Z) ( ]';
10 amount := length(sql_text);
11 dbms_lob.writeappend(sql_code,amount,sql_text);
12
13 for i in 1..1024 loop
14 sql_text := delim||'PARTITION P_'||i||' VALUES LESS THAN ('||i||')';
15 amount := length(sql_text);
16 dbms_lob.writeappend(sql_code,amount,sql_text);
17 delim := ',';
18 end loop;
19
20 dbms_lob.writeappend(sql_code,1,')');
21
22 FOR cur IN (
23 SELECT * FROM dual WHERE NOT EXISTS (
24 SELECT * FROM user_tables WHERE table_name = 'TEST_TAB')
25 ) LOOP
26 EXECUTE IMMEDIATE sql_code;
27 END LOOP;
28
29 dbms_output.put_line(dbms_lob.getlength(lob_loc => sql_code));
30
31 END;
32 /
39877
PL/SQL procedure completed.
SQL> desc test_tab
Имя Пусто? Тип
----------------------------------------- -------- ----------------------------
X NOT NULL NUMBER(38)
Y VARCHAR2(10)
Z NUMBER(38)
SQL> select count(*) from user_tab_partitions where table_name = 'TEST_TAB';
COUNT(*)
----------
1024
【讨论】:
但这意味着我必须手动转义 ddls 中的所有撇号,以便为其创建/查找一些工具 您可以对字符值使用 q[''] Oracle 语法来避免手动操作。 @DmitryNikiforov,带括号的替代引用语法是q'[]'
。
您能否提供更多详细信息或指向此q['']
或q'[]'
的链接?
请看正文部分:docs.oracle.com/cd/E11882_01/server.112/e26088/…以上是关于如何在 oracle 中有条件地执行 DDL?的主要内容,如果未能解决你的问题,请参考以下文章