Adicione uma coluna a uma tabela com um valor padrão igual ao valor de uma coluna existente


88

Como adicionar uma coluna a uma tabela do SQL Server com um valor padrão igual ao valor de uma coluna existente?

Tentei esta instrução T-SQL:

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

mas está dando um erro:

O nome "oldcolumn" não é permitido neste contexto. As expressões válidas são constantes, expressões constantes e (em alguns contextos) variáveis. Nomes de colunas não são permitidos.


6
O valor padrão pode ser uma constante, não outra coluna. Isso precisa de um gatilho, eu acho.
ypercubeᵀᴹ

1
ok, como posso fazer isso, sou novo no sql.
dodos

1
Esse sempre será o padrão ou é apenas para preencher a coluna para as linhas existentes enquanto a nova coluna está sendo adicionada à tabela?
Damien_The_Unbeliever

1
@Damien_The_Unbeliever apenas para preencher a coluna para linhas existentes.
dodos

2
Você tem que fazer isso separadamente UPDATE, então, eu temo.
Damien_The_Unbeliever

Respostas:


70

Experimente isto:

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

5
..sim, mas isso funcionará apenas para as linhas existentes. Não definirá o valor de [nova coluna] quando novas linhas forem inseridas. Você precisa do gatilho APÓS INSERIR etc.
Milão

12
Isso adiciona uma restrição padrão possivelmente não intencional na mesa
Romain Vergnory

1
@RomainVergnory Concordo, é melhor ir sem uma restrição para NOT NULL no início, em seguida, preencher os valores com a coluna existente e depois adicionar NOT NULL novamente
adkl

15

Não gosto muito deles, mas aqui está como você pode fazer isso com um AFTER INSERTgatilho:

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

A AFTER INSERTabordagem do gatilho envolve sobrecarga devido à UPDATEinstrução extra . Eu sugiro usar um INSTEAD OF INSERTgatilho, como segue:

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

Porém, isso não funciona se oldcolumnfor uma coluna de identidade automática.


2
INSTEAD OFgatilhos também não funcionam ao usar tabelas temporais:SYSTEM_VERSIONING = ON
CalvinDale

3

Para estender a resposta de Kapil e evitar a restrição padrão indesejada, tente o seguinte:

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

Substitua -9999 por 'noData' se seu tipo for varchar, nvarchar, datetime, ... ou por qualquer dado compatível para outros tipos: o valor específico não importa, ele será apagado pela 2ª instrução.


1

Você pode usar a coluna computada para inserir uma nova coluna em uma tabela com base em um valor de coluna existente

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

OU, se você quiser fazer algumas alterações no valor com base no valor da coluna existente, use

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

0

Para o meu caso, quero adicionar uma nova coluna exclusiva não nula chamada CODE, mas não sei sobre o valor no momento da criação. Eu defino o valor padrão para ele obtendo um valor padrão de NewID () e atualizando mais tarde.

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

Acho que vai funcionar se você usar Set Identity_Insert <TableName> OFFe após a instrução insert que você escreveu basta usar Set Identity_Insert <TableName> ON.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.