2009-06-25 7 views
22

Potrzebuję dodać nową kolumnę do bazy danych MS SQL 2005 z wartością początkową. Jednak NIE chcę automatycznie tworzyć domyślnego ograniczenia dla tej kolumny. W momencie dodawania kolumny wartość domyślna/początkowa jest poprawna, ale może się ona zmieniać z czasem. Dlatego przyszły dostęp do tabeli MUSI określać wartość zamiast akceptować wartość domyślną.Najlepszy sposób dodania nowej kolumny z początkową (ale nie domyślną) wartością?

Najlepszym mogłem wymyślić jest:

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

To wydaje się nieco nieefektywne stoły largish (100.000 do 1.000.000 rekordy).

Eksperymentowałem z dodaniem kolumny z wartością domyślną, a następnie usunięciem domyślnego ograniczenia. Jednak nie wiem, co to jest nazwa domyślnego ograniczenia i raczej nie powinien uzyskiwać dostępu do sysobjects i umieszczać w bazie wiedzy.

Proszę, musi być lepszy sposób.

Odpowiedz

16

ja bym ALTER TABLE tbl ADD col INTEGER CONSTRAINT tempname DEFAULT 1 pierwszy ,, i upuść wyraźnie nazwie ograniczenie po (prawdopodobnie w ramach transakcji).

+1

+1. --- @Alex: Nie jestem pewien, czy można wykonać DDL w ramach transakcji. --- @Adrian: czy naprawdę zależy Ci na tym, że jest on nieefektywny? Nie robisz tego codziennie, prawda? Zwykle używam tego, co opisujesz dla jasności. – van

+0

@van, nie jestem w 100% pewny ograniczeń SqlServer'05 w tym względzie - PostgreSQL pozwala ci na dokonywanie zmian w tabelach transakcyjnych (przynajmniej BEGIN i COMMIT transakcji). Aby sprawdzić, czy MS również to robi, SELECT @@ TRANCOUNT powinien powiedzieć (nie mogę znaleźć go wyraźnie w dokumentach). –

+0

@van & @Alex MS SQL Server wykonuje DDL w ramach transakcji. –

1

Można zrobić go w wyzwalacz insert

+0

to dokładnie to, co myślę. Przy okazji nie chcesz tego robić jako ograniczenia –

+0

Pytanie dotyczy dodania kolumny do tabeli z istniejącymi wierszami. Dodanie wyzwalacza wpłynie tylko na nowe wiersze. Czy czegoś brakuje? –

+0

Myślę, że źle zrozumiałem pytanie. Kiedy mówisz, że chcesz dodać kolumnę z wartością początkową, czy chcesz, aby wszystkie istniejące wiersze miały tę wartość bez konieczności ich aktualizacji? W takim przypadku możesz dodać dwie kolumny. Jednym z nich jest kolumna z możliwością zerowania, a druga jest kolumną obliczoną. Obliczona kolumna zwróci wartość domyślną, jeśli druga kolumna ma wartość null, w przeciwnym razie zwróci ona drugą kolumnę. To jest dużo złożoności w przyszłości. Wolałbym zrobić to tak, jak zrobiłeś to na swoim przykładzie. –

0

Jeśli dodasz domyślne ograniczenie podczas tworzenia tabeli, nie będziesz wiedział, jak się nazywa. Jeśli jednak dodasz ograniczenie za pomocą ALTER TABLE, musisz nazwać ograniczenie. W takim przypadku będziesz mógł ZMIENIĆ STABILNĄ ZGODĘ (Zależy od T-SQL, nie wiesz o innych bazach danych).

Wymagałoby to jednak CREATE TABLE z kolumną NULL, ALTER TABLE, aby dodać ograniczenie, ustaw kolumnę NOT NULL, a na końcu DROP CONSTRAINT.

Nie wierzę, że wyzwalacz wstawiania zadziała tak, jak ktoś inny wspomniał, ponieważ twoje wiersze są już dodane.

Myślę, że sposób, w jaki opisujesz, może być najbardziej wydajnym i eleganckim rozwiązaniem.

11

Aby dodać kolumnę z wartością domyślną, a następnie usunąć domyślne, można wymienić domyślne:

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

ten wypełniony wartości 1, ale pozostawia tabeli bez domyślny. Używając programu SQL Server 2008, uruchomiłem to i Twój kod, alter update alter i nie zauważyłem żadnej zauważalnej różnicy w tabeli zawierającej 100 000 małych wierszy. Program SSMS nie wyświetlał planów zapytań dotyczących instrukcji tabeli zmian, więc nie mogłem porównać zasobów używanych między tymi dwiema metodami.