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 / 49278
Accepted
Daniel Mann
Daniel Mann
Asked: 2013-09-05 11:08:26 +0800 CST2013-09-05 11:08:26 +0800 CST 2013-09-05 11:08:26 +0800 CST

Publicação de alterações de banco de dados com SSDT que incluem a alteração de tipos de dados de colunas

  • 772

Eu tenho um projeto SQL Server Data Tools (VS2012) que é publicado automaticamente durante o processo de compilação. Uma coluna foi atualizada recentemente de um intpara decimal(18,4). Como resultado dessa alteração, a publicação falha com o erro

(49,1): SQL72014: .Net SqlClient Data Provider: Msg 50000, Level 16, State 127, Line 6 Linhas foram detectadas. A atualização do esquema está terminando porque pode ocorrer perda de dados. (44,0): SQL72045: Erro de execução de script. O script executado: /* O tipo da coluna QuantidadeRecebida na tabela [dbo].[Reconciliação_Recebimento] atualmente é INT NOT NULL, mas está sendo alterado para DECIMAL (18, 4) NOT NULL. Pode ocorrer perda de dados. */

IF EXISTS (selecione top 1 1 de [dbo].[Reconciliation_Receiving]) RAISERROR (N'Rows foram detectadas. A atualização do esquema está terminando porque pode ocorrer perda de dados.', 16, 127) WITH NOWAIT Ocorreu um erro enquanto o lote estava sendo sendo executado.

Entendo por que estou recebendo esse erro e sei que ele pode ser resolvido desativando o sinalizador "Bloquear implantação incremental se ocorrer perda de dados". No entanto, há uma forte oposição à desabilitação desse recurso, portanto, não será uma solução aceitável.

A única outra solução que consigo pensar é fazer o seguinte:

  1. Faça uma tabela temporária e copie o conteúdo da tabela existente na tabela temporária
  2. Truncar a tabela existente
  3. Deixe o SSDT atualizar o tipo de dados
  4. Preencha os dados de volta da tabela temporária

Isso parece terrivelmente desajeitado e ineficiente, no entanto.

Existe uma alternativa melhor?

sql-server ssdt
  • 3 3 respostas
  • 28040 Views

3 respostas

  • Voted
  1. Best Answer
    Mark Storey-Smith
    2013-09-05T12:22:19+08:002013-09-05T12:22:19+08:00

    Fiquei tentado a ignorar essa bandeira também, mas fiquei do lado de seus colegas de trabalho e agora tento lidar com essas questões "corretamente". A rota (marginalmente) menos complicada é usar scripts de pré e pós-implantação para fazer o trabalho com uma renomeação.

    • Renomeie a tabela existente em um script de pré-implantação.
    • Com a tabela existente ausente, a tabela em foco será criada de acordo com a nova definição de esquema.
    • Em uma cópia de script pós-implantação da tabela original renomeada para a nova versão.

    Dependendo da natureza do destino, você pode precisar cuidar de descartar e recriar restrições de chave estrangeira.

    • 6
  2. Alex
    2014-05-14T08:30:56+08:002014-05-14T08:30:56+08:00

    No meu caso eu estava removendo uma coluna de uma tabela.

    A solução fornecida nesta resposta não funcionou para mim, resultou em um invalid object nameerro durante a publicação.

    Descobri que era necessário copiar as linhas da tabela, desabilitar a verificação de restrição e excluir as linhas em um script de pré-implantação e, em seguida, copiar as linhas de volta para a tabela com a inserção de identidade habilitada no script pós-implantação.

    Em Script.PreDeployment.sql:

    -- copy and delete dbo.Table1
    BEGIN TRY
        IF (EXISTS (
            SELECT * FROM INFORMATION_SCHEMA.TABLES 
            WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'Table1_copy'))
        BEGIN
            PRINT 'Dropping Table1_copy'
            DROP TABLE dbo.Table1_copy
        END
    
        PRINT 'Copying dbo.Table1'
    
        SELECT @LastID = MAX(ID), @StartID = MIN(ID)
        FROM dbo.Table1
    
        SET @EndID = @StartID + 1000
    
        SELECT * 
        INTO dbo.Table1_copy 
        FROM dbo.Table1
        WHERE ID BETWEEN @StartID AND @EndId
    
        SET @StartID = @EndID + 1
    
        SET IDENTITY_INSERT dbo.Table1_copy ON
    
        WHILE @StartID < @LastID
        BEGIN
            SET @EndID = @StartID + 1000
    
            INSERT dbo.Table1_copy (ID, Column1, Column2, Column3)
            SELECT ID, Column1, Column2, Column3
            FROM dbo.Table1
            WHERE ID BETWEEN @StartID AND @EndId
    
            SET @StartID = @EndID + 1
        END
    
        SET IDENTITY_INSERT dbo.Table1_copy OFF
    
        PRINT 'Copied dbo.Table1 to dbo.Table1_copy'
    
        EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
    
        PRINT 'Deleting dbo.Table1'
        WHILE EXISTS (SELECT 1 FROM dbo.Table1) 
            DELETE TOP(1000) FROM dbo.Table1
        PRINT 'Deleted dbo.Table1'
    
        PRINT 'SUCCESS: Copy and delete dbo.Table1'
    END TRY
    BEGIN CATCH
        EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
    
        PRINT 'ERROR: Copy and delete dbo.Table1'
        PRINT 'ERROR MESSAGE: ' + ERROR_MESSAGE()
    END CATCH
    GO
    

    Em Script.PostDeployment.sql

    DECLARE @StartID BIGINT, @LastID BIGINT, @EndID BIGINT
    
    -- populate dbo.Table1
    BEGIN TRY
        PRINT 'Populating dbo.Table1'
    
        SET IDENTITY_INSERT dbo.Table1 ON
    
        SELECT @LastID = MAX(ID)
        FROM dbo.Table1_copy
    
        WHILE @StartID < @LastID
        BEGIN
            SET @EndID = @StartID + 1000
    
            INSERT dbo.Table1 (ID, Column1, Column2, Column3)
            SELECT ID, Column1, Column2, Column3
            FROM dbo.Table1
            WHERE ID BETWEEN @StartID AND @EndId
    
            SET @StartID = @EndID + 1
        END
    
        SET IDENTITY_INSERT dbo.Table1 OFF
    
        EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
    
        PRINT 'SUCCESS: Populating dbo.Table1'
    END TRY
    BEGIN CATCH
        SET IDENTITY_INSERT dbo.Table1 OFF
    
        PRINT 'ERROR: Populating dbo.Table1'
        PRINT 'ERROR MESSAGE: ' + ERROR_MESSAGE()
    END CATCH
    GO
    
    • 2
  3. MikeB
    2021-08-24T05:32:25+08:002021-08-24T05:32:25+08:00

    ALTER TABLE tabela_1 ALTER COLUMN [a] decimal (18,2)

    Fará o trabalho neste caso, solução muito mais simples para um script de pré-implantação. Também descobri que alterar o destino antes da publicação evitará que o erro de perda de dados seja gerado.

    Às vezes, o SSDT identificará soluções ALTER TABLE/ALTER COLUMN e as usará na compilação, mas não conheço as regras para tornar isso confiável da perspectiva do usuário. Não sei porque não usa nesse caso. Não há chance de perda de dados com ALTER COLUMN.

    • 0

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

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

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

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

    • 4 respostas
  • Marko Smith

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

    • 10 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
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +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

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