我有一个脚本可以创建很多表,索引,触发器等。我想有条件地运行所有这些DDL。我试图用'if then'包装脚本,但它不起作用
IF exists (select 1 from xxx where yyy) THEN
create table...
create table...
CREATE UNIQUE INDEX ...
CREATE TRIGGER ...
END IF;
我怎样才能实现这一目标?
答案 0 :(得分:4)
其中一种方式:
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;
/
P.S。另一种方法是生成异常并继续SQL * Plus。
file 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。
P.S。还有一个回应的例子 - 希望下面的清洁问题。我只在不存在时创建表。表包含1024个分区和DEFAULT语句中的'字符。文字大小&gt; 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