其中一种方式:
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