AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 6320
Accepted
Martin
Martin
Asked: 2011-09-30 02:31:27 +0800 CST2011-09-30 02:31:27 +0800 CST 2011-09-30 02:31:27 +0800 CST

Modificando a estrutura da tabela dentro de uma transação?

  • 772

No Oracle (e provavelmente em outros lugares), a execução de uma instrução ALTER TABLE fará um commit implícito na transação atual.

Temos uma ferramenta (escrita em Java) que deve modificar um esquema por:

  • adicionando algumas colunas
  • removendo algumas colunas
  • atualizando uma tabela de descrição com o novo layout de esquema

A ferramenta conforme escrita exibirá o layout do esquema atual para o usuário e permitirá que ele o modifique. (Basicamente, adicionando ou removendo colunas de "atributos" personalizadas para algumas tabelas) Quando estiver satisfeito, ele poderá aplicar suas alterações.

Observe: O layout básico do esquema e o fato de que você precisa ALTER TABLE para alterar algumas coisas é predefinido por um padrão e não pode ser alterado por nós, pois outras ferramentas não funcionariam mais.

O problema agora é que não podemos executar essas alterações em uma única transação, pois, AFAIK, não é possível fazer várias instruções ALTER TABLE em uma transação.

Que opções temos para "reverter" ao estado inicial se algo der errado ao aplicar as alterações?

Nota: Alguém aqui propôs PONTO DE RESTAURAÇÃO + FLASHBACK - é uma boa ideia chamar isso a partir desta ferramenta (Java)? (Não controlamos totalmente a instância do banco de dados em alguns sites onde a ferramenta deve ser usada.)

Nota: Oracle 10g2 e superior

oracle schema
  • 6 6 respostas
  • 5544 Views

6 respostas

  • Voted
  1. Best Answer
    Chris Saxon
    2011-09-30T03:30:53+08:002011-09-30T03:30:53+08:00

    Como o DDL implicitamente confirma, a única maneira de "reverter" suas alterações é construir a operação reversa e aplicá-la para reverter a alteração, como afirma a_horse_with_no_name.

    No entanto, construir tal reversão nem sempre será simples. Se os dados puderem ser gravados na tabela entre as modificações de tipo (varchar2(10) -> varchar2(50), número -> varchar2) e reverter isso, você também terá que verificar se os novos dados serão válidos ao reverter para o tipo original (ou realizar alguma conversão). Esteja ciente de que descartar colunas em tabelas grandes pode levar algum tempo e gerar grandes quantidades de refazer.

    Você também deve ter cuidado para não invalidar quaisquer procedimentos armazenados em seu banco de dados e outras dependências de aplicativos como resultado dessas alterações.

    A opção de flashback não irá ajudá-lo neste caso. Depois de fazer alterações DDL em uma tabela, você não pode restaurá-la ao estado anterior usando flashback. Tentar fazer isso dará o erro:

    ORA-01466: não foi possível ler os dados - a definição da tabela foi alterada

    Fazer flashback de seu banco de dados completo seria um exagero e também não seria possível a partir do aplicativo Java - você precisa desligar e montar o banco de dados para concluir esta operação.

    O que levanta a questão de para que serve sua ferramenta. Se você só precisa de uma GUI para as pessoas editarem tabelas, algo como o Oracle SQL Data Modeler pode fazer isso e gerar scripts DDL para você. Estes podem então ser validados, testados, uma reversão apropriada construída e aplicada ao banco de dados. A modificação da estrutura de um banco de dados (de produção) deve ser feita com cuidado e testada para garantir que todas as alterações sejam válidas!

    • 5
  2. a_horse_with_no_name
    2011-09-30T02:41:47+08:002011-09-30T02:41:47+08:00

    A única maneira que consigo pensar (além de migrar para um DBMS que suporte DDL transacional) é escrever sua própria manipulação de "transação DDL", onde você cria a instrução correspondente que reverte a alteração real que você fez.

    "Reverter" uma ADD COLUMN é bastante fácil, pois você só precisa descartar a coluna. Para reverter um DROP COLUMN, a única opção que vejo é renomear a coluna primeiro e depois, quando tudo foi bem-sucedido, descartar todas as colunas renomeadas. Para reverter a "queda virtual", você só precisa renomear a coluna de volta ao seu nome original.

    Outra alternativa poderia ser criar uma cópia das tabelas antes de modificá-las, por exemplo, usando CREATE TABLE backup_table AS SELECT * FROM original_table(mas aparentemente esta não é uma boa solução se as tabelas forem muito grandes)

    O uso do Flashback provavelmente não é muito confiável, pois você não pode confiar na disponibilidade dos dados do flashback. O valor padrão para um tempo de flashback garantido é de 15 minutos. Mas o DBA é livre para escolher um valor menor.

    • 2
  3. Todd Pierce
    2011-10-01T07:45:02+08:002011-10-01T07:45:02+08:00

    A Oracle adicionou um recurso Redefinição baseada em edição para atualizar o esquema do aplicativo principalmente online no 11gR2. Você provavelmente poderia usar isso para atingir seu objetivo.

    • 2
  4. Jimbo
    2011-09-30T07:28:53+08:002011-09-30T07:28:53+08:00

    faça todas as alterações em um conjunto temporário de tabelas.

    quando tudo for concluído com sucesso, aplique todas as alterações nas tabelas reais.

    • 1
  5. Phill W.
    2018-11-15T03:35:27+08:002018-11-15T03:35:27+08:00

    A instrução Oracle DDL é confirmada implicitamente. É o único DBMS com o qual trabalho.

    A " Tabela FlashBack" do Oracle pode retroceder uma tabela para um ponto anterior no tempo... mas não funciona em uma alteração estrutural (ou seja, DDL) nessa tabela.

    "Flashback Database " usa um mecanismo diferente, mas levará todo o banco de dados de volta para antes da mudança, o que você pode não ter permissão para fazer.

    Outra opção que ninguém mencionou é o monólito que é DBMS_REDEFINITION .
    É um pacote enorme, fornecido pela Oracle, que deve gerenciar tudo isso para você, tornando suas alterações de tabela transparentes, contínuas e evitando [quase] qualquer interrupção do serviço. É grande e complicado, mas pode valer a pena o investimento para se familiarizar com isso.

    • 1
  6. Roeland Van Heddegem
    2013-09-17T02:50:11+08:002013-09-17T02:50:11+08:00

    Acho melhor você adicionar uma estrutura onde seus clientes pensam que estão adicionando colunas, mas na verdade eles estão apenas adicionando registros em uma tabela, por exemplo: "Table_Column_DEF". Então você só precisa de uma tabela de ligação entre sua tabela padrão e "Table_Column_DEF", onde você também armazena os valores.

    Com esse método, seus clientes podem adicionar qualquer coluna que desejarem e podem fazer isso em 1 transação. Você tem benefícios de reversão, flashback, etc... Você tem, claro, algumas compensações a considerar:

    1) Coluna de Valor:

    • 1 coluna de valor para cada tipo de dados possível e armazenando tudo em varchar2, clob ou blob.
    • Colunas de valor para todos os tipos de dados possíveis...

    2) Desempenho

    3) Consulta: Você terá que construir isso dinamicamente. Percorrendo todos os registros "Table_Column_DEF" e adicionando-os com um "select (selecione Value_Int de LinkTable onde ...) Value_Int, ... de ..."

    • 0

relate perguntas

  • Backups de banco de dados no Oracle - Exportar o banco de dados ou usar outras ferramentas?

  • ORDER BY usando prioridades personalizadas para colunas de texto

  • Interface sqlplus confortável? [fechado]

  • Como encontrar as instruções SQL mais recentes no banco de dados?

  • Como posso consultar nomes usando expressões regulares?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve