ビルドプロセス中に自動的に公開されるSQL Serverデータツール(VS2012)プロジェクトがあります。最近、列がint
からdecimal(18,4)
に更新されました。この変更の結果、発行はエラーで失敗します
(49,1):SQL72014:.Net SqlClientデータプロバイダー:メッセージ50000、レベル16、状態127、行6行が検出されました。データ損失が発生する可能性があるため、スキーマの更新を終了しています。 (44,0):SQL72045:スクリプト実行エラー。実行されたスクリプト:/ *テーブル[dbo]。[Reconciliation_Receiving]の列QuantityReceivedのタイプは現在INT NOT NULLですが、DECIMAL(18、4)NOT NULLに変更されています。データ損失が発生する可能性があります。 * /
IF EXISTS([dbo]。[Reconciliation_Receiving]から上位1 1を選択します)RAISERROR(N'Rows was detected。実行されています。
私は理解しています理由そのエラーを受信していますが、[データ損失が発生した場合に増分展開をブロックする]フラグを無効にすることで解決できることを知っています。ただし、その機能を無効にすることには非常に強い反対があるため、これは許容できる解決策にはなりません。
私が考えることができる他の唯一の解決策は次のことをすることです:
しかし、それは恐ろしく不格好で非効率的です。
より良い代替案はありますか?
私もそのフラグをバイパスするように誘惑されましたが、同僚の側に降りてきて、これらの問題に「正しく」対処しようとしています。 (少し)扱いにくいルートは、展開前および展開後のスクリプトを使用して、名前変更の作業を行うことです。
ターゲットの性質によっては、もちろん、外部キー制約の削除と再作成に注意する必要があります。
私の場合、テーブルから列を削除していました。
これで提供されたソリューション answer は私にとってうまくいきませんでした、それはinvalid object name
公開中のエラー。
テーブルから行をコピーし、制約チェックを無効にして、配置前スクリプトで行を削除し、配置後スクリプトでID挿入を有効にして、行をテーブルにコピーする必要があることがわかりました。
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
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