前文
今日、SQL Server 2008の列を変更して、データ型をcurrency(18,0)のようなものから(19,2)に変更しました。
SQL Serverから "変更を加えるには、次の表を削除して再作成する必要があります"というエラーが表示されました。
答える前に次を読んでください:
[ツール]►[オプション]►[デザイナ]►[テーブルとデータベースのデザイナ]►チェックボックスをオフにします "テーブルの再作成が必要な変更を保存しない"に、オプションがあることはすでにわかります。 ...だからと答えないでください!
実際の質問
私の実際の質問は、次のように、他の何かに対するものです。
これを行うことによる悪影響/考えられる欠点はありますか?
このチェックボックスをオフにすると、テーブルは実際に削除されて自動的に再作成されますか。
もしそうなら、そのテーブルはソーステーブルの100%正確なレプリカであるか?
SQL ServerのManagement Studioがそれを実行する方法を知るためにプログラムされている唯一の方法である場合にのみ、テーブルは削除されて再作成されます。
そうでなくてもよい場合もあるでしょうが、Management Studioで編集した内容がnotdrop and re-willになることもあります。それはする必要がないので作成しなさい。
問題は、すべてのケースを列挙して、どちらに該当するかを判断するのは非常に面倒なことです。
自分がしていることを隠すビジュアルデザイナーの代わりに ALTER TABLE
をクエリウィンドウで使用するのが好きなのはこのためです(そして率直に言ってバグがあります) - 何が起きるのかは正確にわかっています。テーブルを削除して再作成することが唯一の可能性である場合に備えて準備できます(これはSSMSがそれを行う頻度よりも少ない数です)。
「ツール」 - >「オプション」 - >「デザイナー」ノード - >「テーブルの再作成が必要な変更を保存しない」のチェックを外します。
参照 - このオプションをオフにすると、テーブルの再作成を避けることができます。変更が失われることに。たとえば、SQL Server 2008の変更追跡機能を有効にしてテーブルへの変更を追跡するとします。テーブルを再作成する原因となる操作を実行すると、「現象」に記載されているエラーメッセージが表示されます。ただし、このオプションをオフにすると、テーブルが再作成されたときに既存の変更追跡情報が削除されます。したがって、マイクロソフトでは、オプションをオフにしてこの問題を回避しないことをお勧めします。
次の場合に限り、SQL Serverはテーブルを削除して再作成します。
テーブルの再作成中にメタデータが失われると、データが失われるため、ALTERを使用する方が安全です。
はい、これによる悪影響があります。
このフラグによってブロックされた変更をスクリプト化すると、以下のスクリプトのようになります(ContactのID列を自動番号付けされたIDENTITY列に変換していますが、テーブルには依存関係があります)。以下の実行中に発生する可能性のあるエラーに注意してください。
-
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
GO
ALTER TABLE raw.Contact
DROP CONSTRAINT fk_Contact_AddressType
GO
ALTER TABLE ref.ContactpointType SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.Contact
DROP CONSTRAINT fk_contact_profile
GO
ALTER TABLE raw.Profile SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE raw.Tmp_Contact
(
ContactID int NOT NULL IDENTITY (1, 1),
ProfileID int NOT NULL,
AddressType char(2) NOT NULL,
ContactText varchar(250) NULL
) ON [PRIMARY]
GO
ALTER TABLE raw.Tmp_Contact SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT raw.Tmp_Contact ON
GO
IF EXISTS(SELECT * FROM raw.Contact)
EXEC('INSERT INTO raw.Tmp_Contact (ContactID, ProfileID, AddressType, ContactText)
SELECT ContactID, ProfileID, AddressType, ContactText FROM raw.Contact WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT raw.Tmp_Contact OFF
GO
ALTER TABLE raw.PostalAddress
DROP CONSTRAINT fk_AddressProfile
GO
ALTER TABLE raw.MarketingFlag
DROP CONSTRAINT fk_marketingflag_contact
GO
ALTER TABLE raw.Phones
DROP CONSTRAINT fk_phones_contact
GO
DROP TABLE raw.Contact
GO
EXECUTE sp_rename N'raw.Tmp_Contact', N'Contact', 'OBJECT'
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
Idx_Contact_1 PRIMARY KEY CLUSTERED
(
ProfileID,
ContactID
)
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
Idx_Contact UNIQUE NONCLUSTERED
(
ProfileID,
ContactID
)
GO
CREATE NONCLUSTERED INDEX idx_Contact_0 ON raw.Contact
(
AddressType
)
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
fk_contact_profile FOREIGN KEY
(
ProfileID
) REFERENCES raw.Profile
(
ProfileID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
fk_Contact_AddressType FOREIGN KEY
(
AddressType
) REFERENCES ref.ContactpointType
(
ContactPointTypeCode
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.Phones ADD CONSTRAINT
fk_phones_contact FOREIGN KEY
(
ProfileID,
PhoneID
) REFERENCES raw.Contact
(
ProfileID,
ContactID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE raw.Phones SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.MarketingFlag ADD CONSTRAINT
fk_marketingflag_contact FOREIGN KEY
(
ProfileID,
ContactID
) REFERENCES raw.Contact
(
ProfileID,
ContactID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE raw.MarketingFlag SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.PostalAddress ADD CONSTRAINT
fk_AddressProfile FOREIGN KEY
(
ProfileID,
AddressID
) REFERENCES raw.Contact
(
ProfileID,
ContactID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE raw.PostalAddress SET (LOCK_ESCALATION = TABLE)
GO
COMMIT