从SQL生成更改脚本

时间:2014-03-28 08:04:59

标签: sql oracle

我想将数据库开发从创建更改脚本更改为从声明性定义自动生成更改脚本。我将如何在Oracle DB上为PL / SQL执行此操作?

1 个答案:

答案 0 :(得分:0)

您可以在此处的section "Version Datamodel"上找到有关stackoverflow的简短介绍。多年来,我一直在这个有趣的领域工作,从1994年开始在Oracle7上开始,允许自动隔夜生产。不是所有的夜晚我都睡了......

对于Invantive Producer,我们有一个在Oracle 11及更高版本上运行的启动包,负责自动升级,但它超过了8000行。引导包由PL / SQL在引导时调用,稍后从具有软件定义的存储库中获取指令。存储库在Technical Reference Manual处描述,也可以使用Diagram,可能会给您一些启发。

我可以给你一个例如程序的样本,请让我知道你想自动生成DDL的对象类型,然后我可以在必要时添加东西。

procedure verify_index
( p_table_name   varchar2
, p_index_name   varchar2
, p_index_unique boolean default null
, p_column_list  varchar2
)
;

procedure verify_index
( p_mode         pls_integer
, p_table_name   varchar2
, p_index_name   varchar2
, p_index_unique boolean default null
, p_column_list  varchar2
)
is
begin
  verify_index
  ( get_table_name(p_mode, p_table_name)
  , get_index_name(p_mode, p_index_name)
  , case
    when p_mode = g_history_mode
    then false
    else p_index_unique
    end
  , p_column_list
    || case
       when p_mode = g_history_mode
       then ',h_date_starts,h_date_ends'
       else ''
       end
  )
  ;
end;

--
-- Verify existence of an index with the indicated column list.
--
procedure verify_index
( p_table_name   varchar2
, p_index_name   varchar2
, p_index_unique boolean default null
, p_column_list  varchar2
)
is
  l_index_exists_anywhere boolean;
  l_index_exists_on_table boolean;
  l_create_index          boolean;
  l_ist_column_list       varchar2(4000);
  l_soll_column_list      varchar2(4000);
  l_story                 varchar2(4000);
  l_stmt                  varchar2(4000);
begin
  l_story := 'Reason: ';
  --
  -- Determine whether to recreate the index.
  -- In the process, drop the current index when not correct.
  --
  l_index_exists_anywhere := index_exists(p_index_name, null, null);
  l_index_exists_on_table := index_exists(p_index_name, null, p_table_name);
  if l_index_exists_on_table
  then
    l_ist_column_list := index_column_list(p_index_name, true);
    l_soll_column_list := lower(p_column_list);
    if identical_character_sequence(l_ist_column_list, l_soll_column_list)
    then
      -- Column lists are equal. Just check uniqueness.
      if index_exists(p_index_name, p_index_unique, p_table_name)
      then
        null; -- Do nothing.
        l_create_index := false;
        l_story := l_story || ' index ' || p_index_name || ' already exists on the correct table with the correct column list ' || l_soll_column_list || '. Do nothing.';
      else
        drop_index_existing(p_index_name);
        l_create_index := true;
        l_story := l_story || ' index ' || p_index_name || ' has the correct column list ' || l_soll_column_list || ' but on a different table. Recreate index.';
      end if;
    else
      drop_index_existing(p_index_name);
      l_create_index := true;
      l_story := l_story || ' index ' || p_index_name || ' has the incorrect column list ' || l_ist_column_list || ' but should have ' || l_soll_column_list || '. Recreate index.';
    end if;
  elsif l_index_exists_anywhere
  then
    drop_index_existing(p_index_name);
    l_create_index := true;
    l_story := l_story || ' index ' || p_index_name || ' exists on the wrong table. Recreate index.';
  else
    l_ist_column_list := null;
    l_create_index := true;
    l_story := l_story || ' index ' || p_index_name || ' does not yet exist. Create index.';
  end if;
  --
  -- Now l_create_index describes whether to create the index or not.
  --
  if l_create_index
  then
    /* Only uncomment this when itgen_log is available. During bootstrapping it is not possible
       to use itgen_log. */
    -- itgen_log.debug('Create index ' || p_index_name || '. ' || l_story);
    l_stmt := 'create'
              || case
                 when p_index_unique
                 then ' unique'
                 else ''
                 end
              || ' index '
              || p_index_name
              || ' on '
              || p_table_name
              || '('
              || p_column_list
              || ')'
              ;
    execute_dynamic_sql(l_stmt);
  end if;
end
;