Tambahkan kolom ke tabel dengan nilai default yang sama dengan nilai kolom yang sudah ada

90

Bagaimana cara menambahkan kolom ke tabel SQL Server dengan nilai default yang sama dengan nilai kolom yang sudah ada?

Saya mencoba pernyataan T-SQL ini:

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

tetapi memberikan kesalahan:

Nama "oldcolumn" tidak diizinkan dalam konteks ini. Ekspresi yang valid adalah konstanta, ekspresi konstan, dan variabel (dalam beberapa konteks). Nama kolom tidak diizinkan.

doesdos
sumber
6
Nilai default bisa berupa konstanta, bukan kolom lain. Ini membutuhkan pemicu, saya pikir.
ypercubeᵀᴹ
1
ok, bagaimana saya bisa melakukan itu, saya baru mengenal sql.
dilakukan pada
1
Apakah itu akan selalu menjadi default, atau ini hanya untuk mengisi kolom untuk baris yang ada sementara kolom baru ditambahkan ke tabel?
Damien_The_Unbeliever
1
@Damien_The_Unbeliever hanya untuk mengisi kolom untuk baris yang ada.
dilakukan
2
Anda harus melakukannya secara terpisah UPDATE, saya khawatir.
Damien_The_Unbeliever

Jawaban:

73

Coba ini:

ALTER TABLE tablename ADD newcolumn type NOT NULL DEFAULT (0)
Go
Update tablename SET newcolumn = oldcolumn Where newcolumn = 0
Go
Kapil Khandelwal
sumber
5
..ya, tapi ini hanya akan berfungsi untuk baris yang ada. Ini tidak akan menyetel nilai [kolom baru] saat baris baru disisipkan. Anda perlu SETELAH MASUKKAN pemicu dll.
Milan
14
Ini menambahkan batasan default yang mungkin tidak disengaja pada tabel
Romain Vergnory
1
@RomainVergnory Saya setuju, lebih baik tidak ada batasan untuk NOT NULL pada awalnya, lalu isi nilai dengan kolom yang ada dan kemudian tambahkan NOT NULL lagi
adkl
15

Saya tidak terlalu menyukai mereka, tetapi inilah cara Anda melakukan ini dengan AFTER INSERTpemicu:

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ᵀᴹ
sumber
13

The AFTER INSERTPendekatan memicu melibatkan biaya overhead karena tambahan UPDATEpernyataan. Saya sarankan menggunakan INSTEAD OF INSERTpemicu, sebagai berikut:

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

Ini tidak berfungsi meskipun jika itu oldcolumnadalah kolom identitas otomatis.

Herman Kan
sumber
2
INSTEAD OFpemicu juga tidak berfungsi saat menggunakan tabel temporal:SYSTEM_VERSIONING = ON
CalvinDale
3

Untuk memperluas jawaban Kapil , dan menghindari batasan default yang tidak diinginkan, coba ini:

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

Ganti -9999 dengan 'noData' jika tipe Anda adalah varchar, nvarchar, datetime, ... atau dengan data yang kompatibel untuk tipe lain: nilai spesifik tidak masalah, itu akan dihapus oleh instruksi ke-2.

Frédéric Chauvière
sumber
1

Anda dapat menggunakan kolom terhitung untuk menyisipkan kolom baru dalam tabel berdasarkan nilai kolom yang sudah ada

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

ATAU, jika Anda ingin membuat beberapa perubahan pada nilai berdasarkan nilai kolom yang ada, gunakan

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

Untuk kasus saya, saya ingin menambahkan kolom unik bukan null baru bernama CODE tetapi saya tidak tahu tentang nilai pada saat pembuatan. Saya menetapkan nilai default untuk itu dengan mendapatkan nilai default dari NewID () kemudian memperbarui nanti.

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
sumber
-3

Saya pikir ini akan berhasil jika Anda menggunakan Set Identity_Insert <TableName> OFFdan setelah penyisipan Pernyataan yang Anda tulis baru saja digunakan Set Identity_Insert <TableName> ON.

pengguna7040891
sumber