动态创建Oracle表(动态执行DDL)PLS-00103: Encountered the symbol “CREATE“ when expecting one of the following

一、场景:

有一个表结构需要在程序中动态创建,假设表结构为:

create table tb_test(
       id varchar2(20),
       name varchar2(20)
);

然后添加一个索引:

create index idx_tb_test_id ON tb_test (id);

先说解决方案:

declare
  v_sql      varchar2(500);
  v_isexists number;
begin

  -- 检查当前表是否已经存在
  select count(1)
    into v_isexists
    from user_tables
   where table_name = 'tb_test';

  -- 如果未存在则执行DDL语句
  if v_isexists = 0 then
  
    -- 执行建表语句
    v_sql := 'create table tb_test(
       id varchar2(20),
       name varchar2(20)
       )';
    execute immediate v_sql;
  
    -- 执行建索引语句
    v_sql := 'create index idx_tb_test_id ON tb_test (id)';
    execute immediate v_sql;
  
  end if;
end;

二、尝试:

编写语句:

begin
create table tb_test(
       id varchar2(20),
       name varchar2(20)
);
create index idx_tb_test_id ON tb_test (id);
end;

执行报错:

PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:

   ( begin case declare exit for goto if loop mod null pragma
   raise return select update while with 
     <<
   continue close current delete fetch lock insert open rollback
   savepoint set sql execute commit forall merge pipe purge

看起来像是有create类的DDL语句不可以在begin里执行。

那么试一下不写begin是否可行,执行以下语句:

create table tb_test(
       id varchar2(20),
       name varchar2(20)
);
create index idx_tb_test_id ON tb_test (id);

报错:

ORA-00911: 无效字符

当没有begin和end时,遇到;字符就会有这个错误,这个办法同样不可行。

三、解决方案:

可以使用execute immediate '' 方式执行语句:

declare
  v_sql      varchar2(500);
  v_isexists number;
begin

  -- 检查当前表是否已经存在
  select count(1)
    into v_isexists
    from user_tables
   where table_name = 'tb_test';

  -- 如果未存在则执行DDL语句
  if v_isexists = 0 then
  
    -- 执行建表语句
    v_sql := 'create table tb_test(
       id varchar2(20),
       name varchar2(20)
       )';
    execute immediate v_sql;
  
    -- 执行建索引语句
    v_sql := 'create index idx_tb_test_id ON tb_test (id)';
    execute immediate v_sql;
  
  end if;
end;

注意点:

 1、execute immediate每次只可执行一条DDL语句

 2、执行的语句中句尾不可带有;符号

你可能感兴趣的:(oracle,ddl,sql)