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.


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

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   

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ą.


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ę.


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;

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])

-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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.