Negative Auswirkungen "Speichern von Änderungen verhindern, bei denen die Tabelle neu erstellt werden muss"


255

Präambel

Ich habe heute eine Spalte in SQL Server 2008 geändert und den Datentyp von Währung (18,0) in (19,2) geändert.

Ich habe die Fehlermeldung "Die von Ihnen vorgenommenen Änderungen erfordern, dass die folgenden Tabellen gelöscht und neu erstellt werden" von SQL Server erhalten.

Bevor Sie zur Antwort kommen, lesen Sie bitte Folgendes:

Ich weiß bereits, dass es die Option unter Extras ► Optionen ► Designer ► Tabellen- und Datenbankdesigner gibt. ► Deaktivieren Sie das Kontrollkästchen "Speichern von Änderungen verhindern, die eine Neuerstellung der Tabelle erfordern". Verhindern Sie das Speichern von Änderungen, die eine Neuerstellung der Tabelle erfordern, mit fünf Klicks ... also antworte nicht damit!

Aktuelle Frage

Meine eigentliche Frage ist für etwas anderes wie folgt:

Gibt es irgendwelche negativen Auswirkungen / möglichen Nachteile dabei?

Wird die Tabelle tatsächlich gelöscht und automatisch neu erstellt, wenn dieses Kontrollkästchen deaktiviert ist?

Wenn ja, ist die Tabellenkopie eine 100% exakte Kopie der Quelltabelle?


65
Extras> Optionen> Designer ... das war es, wonach ich gesucht habe! Vielen Dank!
Nrod


2
Und wenn Sie mit MS SQL Server 2014 arbeiten -> Extras> Optionen> Designer Über das Hauptmenü.
Vityata

Antworten:


89

Die Tabelle wird nur gelöscht und neu erstellt, wenn nur so das Management Studio von SQL Server so programmiert wurde, dass es weiß, wie es geht.

Es gibt sicherlich Fälle, in denen dies der Fall ist, wenn dies nicht erforderlich ist, aber es gibt auch Fälle, in denen Änderungen, die Sie in Management Studio vornehmen, nicht gelöscht und neu erstellt werden, da dies nicht erforderlich ist.

Das Problem ist, dass es ziemlich mühsam sein wird, alle Fälle aufzuzählen und zu bestimmen, auf welche Seite der Linie sie fallen.

Aus diesem Grund verwende ich gerne ALTER TABLEin einem Abfragefenster anstelle von visuellen Designern, die verbergen, was sie tun (und ehrlich gesagt Fehler haben). Ich weiß genau, was passieren wird, und kann mich auf Fälle vorbereiten, in denen die einzige Möglichkeit besteht ist, die Tabelle zu löschen und neu zu erstellen (das ist eine Zahl weniger als die Häufigkeit, mit der SSMS Ihnen das antut).


5
Obwohl es eine wirklich gute Antwort ist, denke ich, dass sie nicht alle vom OP aufgeworfenen Fragen beantwortet, und diese Fragen interessieren mich tatsächlich. Gibt es insbesondere negative Auswirkungen / mögliche Nachteile? und wenn ja, ist die Tabellenkopie eine 100% exakte Nachbildung der Quelltabelle? . Haben Sie Informationen zu diesen Fragen?
Tfrascaroli

252

Extras -> Optionen -> Designerknoten -> Deaktivieren Sie " Speichern von Änderungen verhindern, die eine Tabellenerstellung erfordern ".


12

Referenz - Wenn Sie diese Option deaktivieren, können Sie vermeiden, dass eine Tabelle neu erstellt wird. Außerdem können Änderungen verloren gehen. Angenommen, Sie aktivieren die Änderungsverfolgungsfunktion in SQL Server 2008, um Änderungen an der Tabelle zu verfolgen. Wenn Sie einen Vorgang ausführen, bei dem die Tabelle neu erstellt wird, wird die Fehlermeldung angezeigt, die im Abschnitt "Symptome" aufgeführt ist. Wenn Sie diese Option jedoch deaktivieren, werden die vorhandenen Änderungsverfolgungsinformationen gelöscht, wenn die Tabelle neu erstellt wird. Microsoft empfiehlt daher, dieses Problem nicht zu umgehen, indem Sie die Option deaktivieren.


11

SQL Server löscht die Tabellen nur und erstellt sie neu, wenn Sie:

  • Fügen Sie eine neue Spalte hinzu
  • Ändern Sie die Einstellung Nullen zulassen für eine Spalte
  • Ändern Sie die Spaltenreihenfolge in der Tabelle
  • Ändern Sie den Spaltendatentyp

Die Verwendung von ALTER ist sicherer, da Ihre Daten verloren gehen, wenn die Metadaten beim erneuten Erstellen der Tabelle verloren gehen.


8
Ihre Liste ist nicht vollständig. Fügen Sie beispielsweise die IDENTITYEigenschaft einer Spalte hinzu oder entfernen Sie sie .
Aaron Bertrand

2
Das Hinzufügen einer neuen Spalte am Ende der Felder, die NULLABLE ist, erfordert keine Neuerstellung der Tabelle.
PseudoToad

2

Ja, dies hat negative Auswirkungen:

Wenn Sie eine Änderung ausschreiben, die durch dieses Flag blockiert ist, erhalten Sie so etwas wie das folgende Skript (alles, was ich in der ID-Spalte in Contact in eine automatisch nummerierte IDENTITY-Spalte verwandle, aber die Tabelle hat Abhängigkeiten). Beachten Sie mögliche Fehler, die auftreten können, während Folgendes ausgeführt wird:

  1. Sogar Microsoft warnt davor, dass dies zu Datenverlust führen kann (dieser Kommentar wird automatisch generiert)!
  2. Fremdschlüssel werden für einen bestimmten Zeitraum nicht erzwungen.
  3. Wenn Sie dies manuell in ssms ausführen und 'EXEC (' INSERT INTO 'schlägt fehl) und Sie die folgenden Anweisungen ausführen lassen (was standardmäßig der Fall ist, da sie durch' go 'geteilt werden), fügen Sie 0 Zeilen ein und löschen sie dann der alte Tisch.
  4. Wenn dies eine große Tabelle ist, kann die Laufzeit der Einfügung groß sein, und die Transaktion enthält eine Schemamodifikationssperre, sodass viele Dinge blockiert werden .

- -

/* 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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.