Aktualisieren der Nullbarkeit von Spalten in SQL 2008

Ich habe einen sehr breiten Tisch, der viel und viele Bitfelder enthält. Diese Bitfelder wurden ursprünglich als nullable eingerichtet. Jetzt haben wir gerade eine Entscheidung getroffen, dass es keinen Sinn macht, sie nullable zu haben der Wert ist entweder Ja oder Nein, Standard-Nr. Mit anderen Worten, das Schema sollte sich ändern von:

create table MyTable( ID bigint not null, Name varchar(100) not null, BitField1 bit null, BitField2 bit null, ... BitFieldN bit null ) 

nach

 create table MyTable( ID bigint not null, Name varchar(100) not null, BitField1 bit not null, BitField2 bit not null, ... BitFieldN bit not null ) alter table MyTable add constraint DF_BitField1 default 0 for BitField1 alter table MyTable add constraint DF_BitField2 default 0 for BitField2 alter table MyTable add constraint DF_BitField3 default 0 for BitField3 

Also bin ich gerade durch das SQL Management Studio gegangen und habe alle diese Felder auf nicht nullable, Standardwert 0 aktualisiert. Und guess was – wenn ich versuche, es zu aktualisieren, erstellt SQL Mgmt Studio intern die Tabelle und versucht dann, alle wieder einzusetzen die data in die neue Tabelle … inklusive der Nullwerte! Was natürlich einen Fehler erzeugt, weil es explizit versucht, einen Nullwert in eine nicht nullable Spalte einzufügen. Aaargh!

Offensichtlich konnte ich N Update Aussagen des Formulars:

 update MyTable set BitField1 = 0 where BitField1 is null update MyTable set BitField2 = 0 where BitField2 is null 

aber wie ich schon sagte, da sind n Felder da draussen, und was mehr ist, muss sich diese Veränderung auf mehrere identische databaseen ausbreiten. Sehr schmerzhaft manuell zu implementieren.

Gibt es eine Möglichkeit, die Tabellenänderung einfach ignorieren die Nullwerte und lassen Sie die Standard-Regel zu treten, wenn Sie versuchen, einen Nullwert insert?

Wenn Sie absolut sicher sind, dass Sie dies für alle Bit-Spalten auf dem Tisch tun möchten, können Sie einen Cursor verwenden, um über diese Spalten zu iterieren und das Skript dynamisch zu erstellen. Das ist ähnlich wie Alexanders Lösung, außer dass es funktioniert, wenn die Spalten nicht nummeriert sind 1..n (was ich bezweifle – ich vermute, dass diese vermutlich zu Illustrationszwecken vereinfacht wurden).

 DECLARE @colName sysname; DECLARE @sql nvarchar(max); DECLARE cur CURSOR LOCAL FAST_FORWARD FOR SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MyTable' AND DATA_TYPE = 'bit' AND IS_NULLABLE = 'YES'; OPEN cur; FETCH NEXT FROM cur INTO @colName; WHILE @@FETCH_STATUS = 0 BEGIN SET @sql = N'UPDATE [MyTable] SET ' + QUOTENAME(@colName) + N' = 0 WHERE ' + QUOTENAME(@colName) + N' IS NULL;' + N'ALTER TABLE [MyTable] ALTER COLUMN ' + QUOTENAME(@colName) + N' bit NOT NULL;' + N'ALTER TABLE [MyTable] ADD CONSTRAINT ' + QUOTENAME('DF_' + @colName) + N' DEFAULT(0) FOR ' + QUOTENAME(@colName) + N';'; EXEC (@sql); -- Replace with PRINT @sql; if you want to test first. FETCH NEXT FROM cur INTO @colName; END CLOSE cur; DEALLOCATE cur; 

Ich denke, nach allem bin ich nur mit den N Update Aussagen gehen. Es ist ein einmaliger Job, das Skript zu schreiben, das meistens copy-and-paste ist, und dann kann ich dieses Skript auf allen zutreffenden databaseen ausführen.

Trotzdem wäre ich interessiert zu wissen, ob es noch eine effizientere Möglichkeit gibt …

 DECLARE @command VARCHAR(8000) DECLARE @index int SET @index=0 WHILE @index<=N DO BEGIN SET @command=@command+'update MyTable SET BitField'+cast(@index as varchar(3))+' = 0 WHERE BitField'+cast(@index as varchar(3))+' IS NULL' EXEC(@command) SET @index=@index+1 END 

und so weiter…