我有一个.sql文件,它有一系列create table语句,如下所示:
crtab.sql
define ll='&1';
define ul='&2';
create table TAB1 (...);
create table TAB2 (...);
create table TAB3 (...);
...
create table TAB1000 (...);
用户将两个参数作为参数传递 - 下限ll
和上限ul
,表示要创建的表编号范围。
例如,
sqlplus crtab.sql 3 67
应该只创建表TAB3
到TAB67
。
如何在.sql
文件中实现此逻辑?
答案 0 :(得分:2)
myArray(1) := 'CREATE TAB 1 ...';
...
myArray(1000) := 'CREATE TAB 1000 ...';
2。 循环ll到ul并执行这些查询, 即。
for i in ll..ul
loop
@sql = myArray(i);
exec @sql;
end loop;
我很抱歉任何语法错误。
答案 1 :(得分:2)
也许喜欢这些
CREATE OR REPLACE PROCEDURE TABS_V1 (ll number, ul number) IS
BEGIN
IF 1 BETWEEN ll AND ul THEN
EXECUTE IMMEDIATE 'create table TAB1 (...)';
END IF;
IF 2 BETWEEN ll AND ul THEN
EXECUTE IMMEDIATE 'create table TAB2 (...)';
END IF;
IF 3 BETWEEN ll AND ul THEN
EXECUTE IMMEDIATE 'create table TAB3 (...)';
END IF;
...
IF 1000 BETWEEN ll AND ul THEN
EXECUTE IMMEDIATE 'create table TAB1000 (...)';
END IF;
END;
CREATE OR REPLACE PROCEDURE TABS_V2 (ll number, ul number) IS
TYPE tabs IS TABLE OF VARCHAR2(4000) INDEX BY NUMBER;
tabs all_tabs;
BEGIN
all_tabs(1) = 'create table TAB1 (...)';
all_tabs(1) = 'create table TAB2 (...)';
all_tabs(1) = 'create table TAB3 (...)';
...
all_tabs(1000) = 'create table TAB1000 (...)';
FOR cnt IN ll .. ul LOOP
EXECUTE IMMEDIATE all_tabs(cnt);
END LOOP;
END;
答案 2 :(得分:1)
假设桌面结构相同,你最好创建&基于你的ll和ul在循环中执行动态sql语句。例如(在sql server语法中)
declare @sql varchar(1000)
declare @i int set @i = @ll
while @i <= @ul begin
set @sql = 'create table TAB' + cast( @i as varchar ) + '(...);'
exec @sql
set @i = @i + 1
end
如果表结构不同,则只需在每个创建周围放置一个if语句。
答案 3 :(得分:1)
有几种方法可以做到这一点。首先,您可以使用匿名块,其中包含语句的嵌套表或语句的关联数组。嵌套表方法对现有脚本的更改要少一些,但存在数字不按顺序排列的风险。请注意,我正在使用替代引用机制,例如q'[character] ... [character]',以防你的DDL包含一些撇号。
此代码与其他一些答案类似,但使用Oracle语法并且不需要创建其他对象。
嵌套表脚本:
--Only create the tables between the two values (nested table)
declare
type varchar_tab is table of varchar2(32767);
table_statements varchar_tab := varchar_tab(
q'!create table tab1 (test1 number)!',
q'!create table tab2 (test1 number)!',
q'!create table tab3 (test1 number)!',
q'!create table tab4 (test1 number)!'
);
begin
for i in &1 .. &2 loop
execute immediate table_statements(i);
end loop;
end;
/
关联数组脚本:
--Only create the tables between the two values (associative array)
declare
type varchar_tab is table of varchar2(32767) index by number;
table_statements varchar_tab;
begin
table_statements(1) := q'!create table tab1 (test1 number)!';
table_statements(2) := q'!create table tab2 (test1 number)!';
table_statements(3) := q'!create table tab3 (test1 number)!';
table_statements(4) := q'!create table tab4 (test1 number)!';
--Only create the tables between the two values
for i in &1 .. &2 loop
execute immediate table_statements(i);
end loop;
end;
/
如果您正在寻找一种方法来保持您的脚本几乎与其当前形式相同,另一种方法是运行整个脚本,然后在最后放置一个匿名块以删除不需要的表。这使得脚本的顶部非常简单,但显然可能存在一些自动删除表的问题。
--Drop all the tables except for those within the range
declare
table_does_not_exist exception;
pragma exception_init(table_does_not_exist, -00942);
begin
for i in 1 .. 1000 loop
if i between &1 and &2 then
null;
else
begin
execute immediate 'drop table tab'||i;
exception when table_does_not_exist then null;
end;
end if;
end loop;
end;
/
答案 4 :(得分:0)
执行此操作的一种方法是使用C预处理程序和#if
指令来包含或不包含在命令行上定义的某些宏上的每个语句。然后运行预处理文件而不是原始文件。