Páginas

quarta-feira, 13 de julho de 2016

[Oracle] - Procedimento para resetar sequences


Bom Pessoal,
 Essa é mais uma Postagem para ajudar em problemas do dia-a-dia, caso faça alguma restauração e os valores das "sequences" do banco estejam desatualizados, esse procedimento corrige a sequencia certa as "sequences" com base nos valores das tabelas informadas na base de dados. Segue abaixo, procedimento para efetuar está manutenção:




declare
  v_owner       VARCHAR2(32) := 'SISTESTE';
  v_nome_tabela VARCHAR2(32);
  v_maxID       NUMBER(18);
  v_sql_max     varchar2(30);
  v_sql_seq_c   VARCHAR2(500);
  v_sql_seq_d   VARCHAR2(500);
  v_sql_seq_m   VARCHAR2(500);
  v_sql_trg     VARCHAR2(500);
  v_erro        VARCHAR2(500);
  CURSOR C_SEQUENCE IS
    SELECT TRIM(T.sequence_name) as nome_sequence, T.*
      FROM ALL_SEQUENCES T
     WHERE T.sequence_owner = v_owner
    --  AND T.SEQUENCE_NAME = 'IDTBCIDADE'
     ORDER BY TRIM(T.sequence_name);
  -------------------------------
  CURSOR C_TABELA(cv_owner IN VARCHAR2, cv_indice IN VARCHAR2) IS
    SELECT unique T0.table_name AS tabela
      FROM all_CONS_COLUMNS T0
     INNER JOIN all_CONSTRAINTS T1
        ON T0.owner = T1.owner
       AND T0.table_name = T1.table_name
       AND TRIM(T0.constraint_name) = TRIM(T1.constraint_name)
     WHERE T0.owner = cv_owner
       AND TRIM(T0.column_name) = TRIM(cv_indice)
       AND T1.constraint_type = 'P';
  ---------------------------------
  CURSOR C_TRIGGER(cv_nome_tabela IN VARCHAR2) IS
    SELECT unique T.trigger_name
      FROM ALL_TRIGGERS T
     WHERE T.owner = v_owner
       AND T.table_name = cv_nome_tabela;
BEGIN
  -----------------------
  -- CARREGA AS SEQUENCES DO OWNER
  -----------------------
  FOR RC_SEQ IN C_SEQUENCE LOOP
    -- LIMPA VARIAVEIS --
    v_sql_seq_c := '';
    v_sql_seq_d := '';
    v_sql_seq_m := '';
    v_sql_trg   := '';
    -- BUSCA O NOME DA TABELA
    BEGIN
      v_nome_tabela := '';
      FOR rc_tabela IN C_TABELA(v_owner, RC_SEQ.nome_sequence) LOOP
        -- PEGA O MAIOR ID
        v_sql_seq_m   := 'SELECT NVL(MAXID,0) FROM(SELECT MAX(' ||
                         TRIM(RC_SEQ.nome_sequence) || ') MAXID FROM ' ||
                         rc_tabela.tabela || ')';
        v_nome_tabela := upper(trim(rc_tabela.tabela));
      END LOOP;
      --------------------------------
      IF v_sql_seq_m IS NOT NULL THEN
        EXECUTE IMMEDIATE v_sql_seq_m
          INTO v_maxID;
      END IF;
      -- DROPA A SEQUENCE
      v_sql_seq_d := 'DROP SEQUENCE ' || v_owner || '.' ||
                     RC_SEQ.nome_sequence;
      IF v_sql_seq_d IS NOT NULL and v_sql_seq_m is not null and
         v_nome_tabela is not null THEN
        EXECUTE IMMEDIATE v_sql_seq_d;
      END IF;
      -- RECRIA A SEQUENCE
      v_maxID     := (v_maxID + 1);
      v_sql_max   := TO_CHAR(v_maxID);
      v_sql_seq_c := 'CREATE SEQUENCE ' || v_owner || '.' ||
                     RC_SEQ.nome_sequence || ' MINVALUE 1' ||
                     ' MAXVALUE 9999999999999999999999999999' ||
                     ' START WITH ' || v_sql_max || ' INCREMENT BY 1' ||
                     ' CACHE 20';
      IF v_sql_seq_c IS NOT NULL and v_nome_tabela is not null THEN
        EXECUTE IMMEDIATE v_sql_seq_c;
      END IF;
      -- RECOMPILA AS TRIGGERS VINCULADAS AS TABELAS
   
      FOR RC_TRG IN C_TRIGGER(v_nome_tabela) LOOP
        BEGIN
          v_sql_trg := 'ALTER TRIGGER "' || v_owner || '"."' ||
                       RC_TRG.trigger_name || '" COMPILE';
          EXECUTE IMMEDIATE v_sql_trg;
        EXCEPTION
          WHEN OTHERS THEN
            v_erro := 'TRIGGER - ERRO: ' || SQLCODE || ' - ' || SQLERRM;
            DBMS_OUTPUT.put_line(v_erro);
            DBMS_OUTPUT.put_line(v_sql_trg);
        END;
      END LOOP;
      -------------------------
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        v_erro := 'A SEQUENCE: ' || v_owner || '.' || RC_SEQ.nome_sequence ||
                  ' NÃO FOI CORRELACIONADA COM NENHUMA TABELA!';
        DBMS_OUTPUT.put_line(v_erro);
      WHEN OTHERS THEN
        v_erro := 'SEQUENCE - ERRO: ' || SQLCODE || ' - ' || SQLERRM;
        DBMS_OUTPUT.put_line(v_erro);
        DBMS_OUTPUT.put_line('ERRO: CRIAÇÃO SEQ -> ' || v_sql_seq_c ||
                             ' TABELA -> ' || v_nome_tabela);
    END;
  END LOOP;
  COMMIT;
EXCEPTION
  WHEN OTHERS THEN
    v_erro := 'GENÉRICO - ERRO: ' || SQLCODE || ' - ' || SQLERRM;
    DBMS_OUTPUT.put_line(v_erro);
END;

Espero que ajude, Fiquem na Paz.

2 comentários: