web-dev-qa-db-fra.com

"Empêcher l'enregistrement des modifications nécessitant la recréation de la table", effets négatifs

Préambule

Aujourd’hui, je modifiais une colonne de SQL Server 2008, en changeant le type de données de quelque chose comme devise (18,0) à (19,2).

J'ai eu l'erreur "Les modifications que vous avez apportées nécessitent que les tables suivantes soient supprimées et recréées" dans SQL Server.

Avant de vous empêcher de répondre, veuillez lire ce qui suit:

Je sais déjà qu’il existe une option dans Outils ► Options ► Concepteur ► Concepteurs de tables et de bases de données ► Désélectionnez la case "Empêcher l’enregistrement des modifications nécessitant la recréation de tables. . " Prevent saving changes that require table re-creation in five clicks ... alors ne répondez pas avec ça!

Question actuelle

Ma question actuelle est pour autre chose, comme suit:

Y at-il des effets négatifs/inconvénients possibles à faire cela?

La table est-elle réellement supprimée et recréée automatiquement lorsque cette case n'est pas cochée?

Si tel est le cas, la table copie-t-elle une réplique exacte à 100% de la table source?

242
CF_HoneyBadger

La table n'est supprimée et recréée que dans les cas où seul le logiciel Management Studio de SQL Server a été programmé pour savoir comment procéder.

Il y a certainement des cas où cela sera fait quand ce n'est pas nécessaire, mais il y aura aussi des cas où les modifications que vous apporterez dans Management Studio seront non déposer et recréer parce que ce n'est pas nécessaire.

Le problème est qu'énumérer tous les cas et déterminer de quel côté de la ligne ils tombent sera assez fastidieux.

C’est pourquoi j’aime utiliser ALTER TABLE dans une fenêtre de requête, au lieu des concepteurs visuels qui cachent ce qu’ils font (et qui ont franchement des bogues) - Je sais exactement ce qui va se passer Cela peut arriver, et je peux me préparer aux cas où la seule possibilité est de supprimer et de recréer le tableau (ce qui est un nombre inférieur à la fréquence à laquelle SSMS vous le fera).

86
Aaron Bertrand

Outils -> Options -> nœud Concepteurs -> Décocher " Empêcher l'enregistrement des modifications nécessitant la création de tables ".

246
Antoine Meltzheim

Référence - La désactivation de cette option peut vous aider à éviter de recréer une table, mais peut également entraîner la perte de modifications. Par exemple, supposons que vous activiez la fonctionnalité Suivi des modifications dans SQL Server 2008 pour suivre les modifications apportées à la table. Lorsque vous effectuez une opération provoquant la recréation de la table, vous recevez le message d'erreur mentionné dans la section "Symptômes". Toutefois, si vous désactivez cette option, les informations de suivi des modifications existantes sont supprimées lorsque la table est recréée. Par conséquent, Microsoft vous recommande de ne pas contourner ce problème en désactivant l'option.

11
user1499112

SQL Server supprime et recrée les tables uniquement si vous:

  • Ajouter une nouvelle colonne
  • Modifier le paramètre Autoriser les valeurs Null pour une colonne
  • Changer l'ordre des colonnes dans la table
  • Changer le type de données de la colonne

Utiliser ALTER est plus sûr, car au cas où les métadonnées seraient perdues lors de la recréation de la table, vos données seraient perdues.

11
Carol Baker West

Oui, cela a des effets négatifs:

Si vous écrivez une modification bloquée par cet indicateur par script, vous obtenez quelque chose comme le script ci-dessous (tout est en train de transformer la colonne ID de Contact en une colonne IDENTITY numérotée automatiquement, mais le tableau a des dépendances). Notez les erreurs potentielles pouvant survenir pendant l'exécution de ce qui suit:

  1. Même Microsoft prévient que cela pourrait entraîner une perte de données (ce commentaire est généré automatiquement)!
  2. pendant un certain temps, les clés étrangères ne sont pas appliquées.
  3. si vous l'exécutez manuellement dans ssms et que l'option 'EXEC (' INSERT INTO 'échoue et que vous laissez les instructions suivantes s'exécuter (ce qu'ils font par défaut, car ils sont divisés par' go '), vous insérerez 0 ligne, puis supprimez la vieille table.
  4. s'il s'agit d'une table volumineuse, l'exécution de l'insertion peut être volumineuse et la transaction détient un verrou de modification de schéma. Bloque donc plusieurs choses.

-

/* 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
2
Andrew Hill