Dodaj kolumnę do tabeli z wartością domyślną równą wartości istniejącej kolumny

90

Jak dodać kolumnę do tabeli SQL Server z domyślną wartością równą wartości istniejącej kolumny?

Wypróbowałem tę instrukcję T-SQL:

ALTER TABLE tablename 
ADD newcolumn type NOT NULL DEFAULT (oldcolumn) 

ale daje błąd:

W tym kontekście nazwa „stara kolumna” jest niedozwolona. Prawidłowe wyrażenia to stałe, stałe wyrażenia i (w niektórych kontekstach) zmienne. Nazwy kolumn są niedozwolone.

diddos
źródło
6
Wartość domyślna może być stałą, a nie inną kolumną. Myślę, że to wymaga wyzwalacza.
ypercubeᵀᴹ
1
ok, jak mogę to zrobić, jestem nowy w sql.
dosdos
1
Czy zawsze będzie to ustawienie domyślne, czy tylko do wypełnienia kolumny dla istniejących wierszy, podczas gdy nowa kolumna jest dodawana do tabeli?
Damien_The_Unbeliever
1
@Damien_The_Unbeliever tylko do wypełnienia kolumny dla istniejących wierszy.
dosdos
2
UPDATEObawiam się, że musisz to zrobić osobno .
Damien_The_Unbeliever

Odpowiedzi:

73

Spróbuj tego:

ALTER TABLE tablename ADD newcolumn type NOT NULL DEFAULT (0)
Go
Update tablename SET newcolumn = oldcolumn Where newcolumn = 0
Go
Kapil Khandelwal
źródło
5
.. tak, ale zadziała to tylko w przypadku istniejących wierszy. Nie ustawi wartości [newcolumn] po wstawieniu nowych wierszy. Potrzebujesz spustu AFTER INSERT itp.
Mediolan
14
To dodaje prawdopodobnie niezamierzone domyślne ograniczenie na stole
Romain Vergnory
1
@RomainVergnory Zgadzam się, lepiej najpierw przejść bez ograniczeń, aby NIE NULL, następnie wypełnić wartości istniejącą kolumną, a później ponownie dodać NOT NULL
adkl
15

Nie lubię ich bardzo, ale oto jak można to zrobić za pomocą AFTER INSERTspustu:

CREATE TRIGGER TableX_AfterInsert_TRG 
  ON TableX 
AFTER INSERT
AS
  UPDATE TableX AS t
  SET t.newcolumn = t.oldcolumn
  FROM Inserted AS i
  WHERE t.PK = i.PK ;              -- where PK is the PRIMARY KEY of the table   
ypercubeᵀᴹ
źródło
13

AFTER INSERTPodejście wyzwalania obejmuje napowietrznych ze względu na dodatkowym UPDATEoświadczeniu. Sugeruję użycie INSTEAD OF INSERTwyzwalacza w następujący sposób:

CREATE TRIGGER tablename_on_insert ON tablename 
INSTEAD OF INSERT 
AS
INSERT INTO tablename (oldcolumn, newcolumn)
SELECT oldcolumn, ISNULL(newcolumn, oldcolumn)
FROM inserted

Nie działa to jednak, jeśli oldcolumnjest to kolumna z automatyczną tożsamością.

Herman Kan
źródło
2
INSTEAD OFwyzwalacze również nie działają podczas korzystania z tabel czasowych:SYSTEM_VERSIONING = ON
CalvinDale,
3

Aby rozszerzyć odpowiedź Kapila i uniknąć niechcianego domyślnego ograniczenia, spróbuj tego:

ALTER TABLE tablename ADD newcolumn type NOT NULL CONSTRAINT DF_TMP_TABLENAME_NEWCOLUMN DEFAULT -9999
Go
Update tablename SET newcolumn = oldcolumn
Go
ALTER TABLE tablename DROP CONSTRAINT DF_TMP_TABLENAME_NEWCOLUMN
Go

Zastąp -9999 przez „noData”, jeśli typ to varchar, nvarchar, datetime, ... lub dowolne zgodne dane dla innych typów: określona wartość nie ma znaczenia, zostanie wyczyszczona przez drugą instrukcję.

Frédéric Chauvière
źródło
1

Możesz użyć kolumny obliczonej, aby wstawić nową kolumnę do tabeli na podstawie istniejącej wartości kolumny

ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn) PERSISTED;

LUB, jeśli chcesz wprowadzić zmiany w wartości na podstawie istniejącej wartości kolumny, użyj

ALTER TABLE dbo.TableName ADD NewColumn AS (OldColumn * 1.5) PERSISTED;
Vijai
źródło
0

W moim przypadku chcę dodać nową unikalną kolumnę o nazwie CODE, która nie jest pusta, ale nie wiem, jaka jest wartość w czasie tworzenia. Ustawiam wartość domyślną, pobierając wartość domyślną z NewID (), a następnie aktualizuję ją później.

ALTER TABLE [WIDGET] ADD [CODE] CHAR(5) NOT NULL DEFAULT(SUBSTRING(CONVERT(CHAR(36), NEWID()), 1, 5))

ALTER TABLE [dbo].[WIDGET] WITH CHECK ADD CONSTRAINT [UQ_WIDGET_CODE] UNIQUE ([CODE])
Trần Thanh Phong
źródło
-3

Myślę, że zadziała, jeśli użyjesz Set Identity_Insert <TableName> OFFi po wstawieniu instrukcji, którą napisałeś, po prostu użyj Set Identity_Insert <TableName> ON.

user7040891
źródło