Fügen Sie einer Tabelle eine Spalte mit einem Standardwert hinzu, der dem Wert einer vorhandenen Spalte entspricht


88

Wie füge ich einer SQL Server-Tabelle eine Spalte mit einem Standardwert hinzu, der dem Wert einer vorhandenen Spalte entspricht?

Ich habe diese T-SQL-Anweisung ausprobiert:

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

aber es gibt einen Fehler:

Der Name "oldcolumn" ist in diesem Zusammenhang nicht zulässig. Gültige Ausdrücke sind Konstanten, konstante Ausdrücke und (in einigen Kontexten) Variablen. Spaltennamen sind nicht zulässig.


6
Der Standardwert kann eine Konstante sein, keine andere Spalte. Das braucht einen Auslöser, denke ich.
Ypercubeᵀᴹ

1
ok, wie kann ich das machen, ich bin neu in sql.
Doesdos

1
Wird dies immer die Standardeinstellung sein oder dient dies nur zum Auffüllen der Spalte für vorhandene Zeilen, während die neue Spalte zur Tabelle hinzugefügt wird?
Damien_The_Unbeliever

1
@Damien_The_Unbeliever nur zum Auffüllen der Spalte für vorhandene Zeilen.
Doesdos

2
Sie müssen es dann als separate tun UPDATE, fürchte ich.
Damien_The_Unbeliever

Antworten:


70

Versuche dies:

ALTER TABLE tablename ADD newcolumn type NOT NULL DEFAULT (0)
Go
Update tablename SET newcolumn = oldcolumn Where newcolumn = 0
Go

4
..yes, aber dies funktioniert nur für die vorhandenen Zeilen. Der Wert [newcolumn] wird beim Einfügen neuer Zeilen nicht festgelegt. Sie benötigen AFTER INSERT Trigger etc.
Milan

12
Dies fügt eine möglicherweise unbeabsichtigte Standardeinschränkung für die Tabelle hinzu
Romain Vergnory

1
@RomainVergnory Ich stimme zu, es ist besser, zunächst ohne Einschränkung auf NOT NULL zu gehen, dann Werte mit der vorhandenen Spalte zu
füllen

15

Ich mag sie nicht sehr, aber hier ist, wie Sie dies mit einem AFTER INSERTAuslöser tun können :

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

Der AFTER INSERTTrigger-Ansatz ist aufgrund der zusätzlichen UPDATEAnweisung mit einem Overhead verbunden . Ich schlage vor, einen INSTEAD OF INSERTAuslöser wie folgt zu verwenden:

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

Dies funktioniert jedoch nicht, wenn oldcolumnes sich um eine Spalte mit automatischer Identität handelt.


2
INSTEAD OFTrigger funktionieren auch nicht, wenn SYSTEM_VERSIONING = ON
Zeittabellen

3

Versuchen Sie Folgendes , um Kapils Antwort zu erweitern und die unerwünschte Standardeinschränkung zu vermeiden:

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

Ersetzen Sie -9999 durch 'noData', wenn Ihr Typ varchar, nvarchar, datetime, ... oder durch kompatible Daten für andere Typen ist: Ein bestimmter Wert spielt keine Rolle, er wird durch die 2. Anweisung gelöscht.


1

Sie können eine berechnete Spalte verwenden, um eine neue Spalte basierend auf einem vorhandenen Spaltenwert in eine Tabelle einzufügen

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

ODER, wenn Sie einige Änderungen am Wert basierend auf dem vorhandenen Spaltenwert vornehmen möchten, verwenden Sie

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

0

In meinem Fall möchte ich eine neue, nicht null eindeutige Spalte mit dem Namen CODE hinzufügen, aber ich weiß nichts über den Wert zum Zeitpunkt der Erstellung. Ich habe den Standardwert dafür festgelegt, indem ich einen Standardwert von NewID () erhalten und später aktualisiert habe.

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

Ich denke, es wird funktionieren, wenn Sie Set Identity_Insert <TableName> OFFund nach der Einfügeanweisung, die Sie geschrieben haben, nur verwenden Set Identity_Insert <TableName> ON.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.