2009-06-25 8 views
22

Devo aggiungere una nuova colonna a un database MS SQL 2005 con un valore iniziale. Tuttavia, NON voglio creare automaticamente un vincolo predefinito su questa colonna. Nel momento in cui aggiungo la colonna il valore predefinito/iniziale è corretto, ma questo può cambiare nel tempo. Quindi, l'accesso futuro alla tabella DEVE specificare un valore invece di accettare un valore predefinito.Il modo migliore per aggiungere una nuova colonna con un valore iniziale (ma non predefinito)?

Il meglio che ho potuto venire in mente è:

ALTER TABLE tbl ADD col INTEGER NULL 
UPDATE tbl SET col = 1 
ALTER TABLE tbl ALTER COLUMN col INTEGER NOT NULL 

Questo sembra un po 'inefficiente per tavoli abbastanza grande (da 100.000 a 1.000.000 record).

Ho sperimentato l'aggiunta della colonna con un valore predefinito e quindi l'eliminazione del vincolo predefinito. Tuttavia, non so quale sia il nome del vincolo predefinito e preferisco non accedere agli sysobjects e inserire conoscenze specifiche del database.

Per favore, ci deve essere un modo migliore.

risposta

16

avevo ALTER TABLE tbl ADD col INTEGER CONSTRAINT tempname DEFAULT 1 prima ,, e rilasciare i chiamato esplicitamente vincolo dopo (presumibilmente all'interno di una transazione).

+1

+1. --- @Alex: non sono sicuro che si possa fare DDL all'interno di una transazione. --- @Adrian: ti interessa davvero che sia inefficiente? Non lo fai tutti i giorni, vero? Di solito uso il modo in cui descrivi per chiarezza. – van

+0

@van, non sono sicuro al 100% delle limitazioni di SqlServer'05 a questo proposito - PostgreSQL ti consente di modificare la tabella in modo transazionale (con BEGIN e COMMIT espliciti della transazione, almeno). Per verificare se anche MS lo fa, SELECT @@ TRANCOUNT dovrebbe dirti (non riesco a trovarlo chiaramente nei documenti). –

+0

@van & @Alex MS SQL Server esegue DDL all'interno delle transazioni. –

1

Lo si può fare in un trigger di inserimento

+0

questo è esattamente quello che penso. bw e non vuoi farlo come vincolo –

+0

La domanda è per aggiungere una colonna a una tabella con righe esistenti. L'aggiunta di un trigger inciderà solo sulle nuove righe. Mi sto perdendo qualcosa? –

+0

Penso di aver frainteso la domanda. Quando dici di voler aggiungere una colonna con un valore iniziale, intendi che desideri che tutte le righe esistenti abbiano questo valore senza doverle aggiornare? In questo caso, potresti aggiungere due colonne. Uno è una colonna nullable e l'altra è una colonna calcolata. La colonna calcolata restituirà il valore predefinito se l'altra colonna è nullo, altrimenti restituirà l'altra colonna. Questa è una grande complessità in futuro. Preferirei farlo come hai fatto nel tuo esempio. –

0

Se si aggiunge un vincolo predefinito durante la creazione della tabella, non si sa come viene chiamato. Tuttavia, se si aggiunge un vincolo con ALTER TABLE, è necessario assegnare un nome al vincolo. In questo caso, si sarà in grado di ALTER TABLE DROP CONSTRAINT (Questo si applica a T-SQL, non è sicuro su altri database.)

Tuttavia, questo richiederebbe CREARE TABELLA con colonna NULL, ALTER TABLE per aggiungere il vincolo, rendere la colonna NOT NULL e infine DROP CONSTRAINT.

Non credo che un trigger di inserimento funzioni come menzionato da qualcun altro, perché le tue righe sono già state aggiunte.

Penso che il modo in cui descrivi possa, in effetti, essere la soluzione più efficiente ed elegante.

11

per aggiungere la colonna con un valore predefinito e quindi eliminare il valore di default, è possibile assegnare un nome di default:

ALTER TABLE tbl ADD col INTEGER NOT NULL CONSTRAINT tbl_temp_default DEFAULT 1 
ALTER TABLE tbl drop constraint tbl_temp_default 

Questa compilato il valore 1, ma lascia il tavolo senza un default. Utilizzando SQL Server 2008, ho eseguito questo e il codice, di alter update alter e non ho visto alcuna differenza evidente su una tabella di 100.000 piccole righe. SSMS non mi mostrava i piani di query per le istruzioni alter tabelle, quindi non ero in grado di confrontare le risorse utilizzate tra i due metodi.

Problemi correlati