"Impedisci di salvare le modifiche che richiedono di ricreare la tabella" effetti negativi


255

Preambolo

Oggi stavo modificando una colonna in SQL Server 2008, cambiando il tipo di dati da qualcosa come la valuta (18,0) a (19,2).

Ho ricevuto l'errore "Le modifiche apportate richiedono che le seguenti tabelle vengano eliminate e ricreate" da SQL Server.

Prima di arrampicarti per rispondere, leggi quanto segue:

So già che c'è un'opzione in Strumenti ► Opzioni ► Designer ► Progettazione tabelle e database ► Deseleziona la casella "Impedisci il salvataggio delle modifiche che richiedono la ricostruzione della tabella". Impedisci il salvataggio delle modifiche che richiedono la ricostruzione della tabella in cinque clic ... quindi non rispondere con quello!

Domanda reale

La mia vera domanda è per qualcos'altro, come segue:

Ci sono effetti negativi / possibili inconvenienti nel fare questo?

La tabella viene effettivamente eliminata e ricreata automaticamente quando questa casella è deselezionata?

In tal caso, la tabella è una copia esatta al 100% della tabella di origine?


65
Strumenti> Opzioni> Designer ... quello che stavo cercando! Grazie!
Nrod

1

2
E se sei con MS SQL Server 2014 -> Extra> Opzioni> Designer Dal menu in alto.
Vityata,

Risposte:


89

La tabella viene eliminata e ricreata solo nei casi in cui è l'unico modo in cui Management Studio di SQL Server è stato programmato per sapere come farlo.

Ci sono certamente casi in cui lo farà quando non è necessario, ma ci saranno anche casi in cui le modifiche apportate in Management Studio non verranno eliminate e ricreate perché non è necessario.

Il problema è che enumerare tutti i casi e determinare da quale parte della linea cadono sarà abbastanza noioso.

Questo è il motivo per cui mi piace usare ALTER TABLEin una finestra di query, invece di visual designer che nascondono ciò che stanno facendo (e francamente hanno dei bug) - So esattamente cosa succederà e posso prepararmi per casi in cui l'unica possibilità è eliminare e ricreare la tabella (che è un numero inferiore rispetto alla frequenza con cui SSMS lo farà).


5
Sebbene sia davvero una buona risposta, ritengo che non fornisca risposte a tutte le domande sollevate dall'OP, e quelle domande sono quelle a cui sono interessato, in realtà. In particolare ci sono effetti negativi / possibili inconvenienti nel fare questo? e in tal caso, la tabella è una copia esatta al 100% della tabella di origine? . Hai qualche informazione riguardo a queste domande?
Tfrascaroli,

252

Strumenti -> Opzioni -> nodo Progettisti -> Deseleziona " Impedisci il salvataggio delle modifiche che richiedono la ricreazione della tabella ".


12

Riferimento : la disattivazione di questa opzione può aiutarti a evitare di ricreare una tabella, ma può anche portare alla perdita di modifiche. Ad esempio, supponiamo di abilitare la funzionalità di rilevamento delle modifiche in SQL Server 2008 per tenere traccia delle modifiche alla tabella. Quando si esegue un'operazione che consente di ricreare la tabella, viene visualizzato il messaggio di errore menzionato nella sezione "Sintomi". Tuttavia, se si disattiva questa opzione, le informazioni di tracciamento delle modifiche esistenti vengono eliminate quando viene ricreata la tabella. Pertanto, Microsoft consiglia di non aggirare questo problema disattivando l'opzione.


11

SQL Server elimina e ricrea le tabelle solo se:

  • Aggiungi una nuova colonna
  • Modificare l'impostazione Consenti null per una colonna
  • Cambia l'ordine delle colonne nella tabella
  • Modifica il tipo di dati della colonna

L'uso di ALTER è più sicuro, poiché nel caso in cui i metadati vengano persi mentre si ricrea la tabella, i dati andranno persi.


8
La tua lista non è esaustiva. Aggiungi / rimuovi la IDENTITYproprietà su una colonna, per esempio.
Aaron Bertrand,

2
L'aggiunta di una nuova colonna alla fine dei campi NULLABLE non richiede una ricostruzione della tabella.
PseudoToad,

2

Sì, ci sono effetti negativi da questo:

Se si elabora una modifica bloccata da questo flag, si ottiene qualcosa di simile allo script seguente (tutto ciò che sto trasformando la colonna ID in Contatto in una colonna IDENTITÀ numerata automaticamente, ma la tabella presenta dipendenze). Nota potenziali errori che possono verificarsi mentre è in esecuzione quanto segue:

  1. Anche microsoft avverte che ciò potrebbe causare la perdita di dati (quel commento viene generato automaticamente)!
  2. per un periodo di tempo, le chiavi esterne non vengono applicate.
  3. se lo esegui manualmente in ssms e 'EXEC (' INSERT INTO 'fallisce, e lasci correre le seguenti istruzioni (cosa che fanno di default, dato che sono divise per' go ') allora inserirai 0 righe, quindi rilascerai il vecchio tavolo.
  4. se si tratta di una tabella grande, il tempo di esecuzione dell'inserto può essere elevato e la transazione contiene un blocco di modifica dello schema, quindi blocca molte cose.

-

/* 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.