简体   繁体   中英

Generate change scripts from SQL

I want to change database development from creating change scripts to automatically generating change scripts from the declarative defitinitions. How would I go about doing that for PL/SQL on an Oracle DB?

You can find a short introduction at section "Version Datamodel" here on stackoverflow. I've worked on this interesting area for many years, starting in 1994 on Oracle7 to allow automatic overnight going in production. Not all nights I got my sleep...

For Invantive Producer, we have a boot-package that runs on Oracle 11 and up and takes care of automatic upgrades, but it is over 8.000 lines. The boot package is called by PL/SQL when bootstrapping and later on takes it instructions from a repository with software definitions. The repository is described at Technical Reference Manual , also a Diagram is available and might give some inspiration.

I can give you a sample of such as procedure, please let me know what types of objects you would like to automatically generate DDL for, then I can add things when necessary.

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

and

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
;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM