Как добавить столбец NOT NULL FOREIGN KEY в существующую (заполненную) таблицу в MS SQL? - PullRequest
8 голосов
/ 11 марта 2010

Мне нужно добавить столбец NOT NULL в существующую (заполненную) таблицу, которая будет внешним ключом для другой таблицы. Это вызывает две проблемы:

  1. Когда вы добавляете столбец, его значение не может быть нулевым - использование значения по умолчанию не является опцией (если только оно не будет удалено позднее), поскольку логика базы данных используется при проверке на стороне сервера, когда пользователь вводит новый запись, т. е. когда приложение пытается добавить запись с этим полем, имеющим нулевое значение, база данных выдает ошибку, которую приложение перехватывает и возвращает пользователю, предлагая им исправить это.

  2. Столбец имеет ограничение внешнего ключа, то есть его значение ДОЛЖНО существовать и во внешней таблице.

Как лучше всего это сделать?

Ответы [ 2 ]

16 голосов
/ 11 марта 2010

Создать столбец, но разрешить NULL. Заполните столбец правильными данными из таблицы внешнего ключа. Изменить столбец добавить не ноль. Добавьте ограничение внешнего ключа.

1 голос
/ 27 мая 2017

По частям ваших вопросов (оф после лет):

1 . Если вы имеете в виду, что значение по умолчанию будет чем-то таким умным, и вам не нужно будет менять его в будущем, тогда ваше желание неверно. почему?

по двум причинам:

  • a) В концепции значения по умолчанию (в каждом программировании
    ) языки, базы данных и так далее ...) значение по умолчанию не то, что Замените значение динамически на то, что вы хотите. За пример Func Sum (a, b, c = 10), в этом случае, если вы не введете параметр c, он будет принят за 10, в противном случае вы должны ввести
    что-то вместо поэтому значения по умолчанию предсказуемы и вычислимы
    значения, НЕ умные значения.
  • b) Внешние ключи являются чем-то более чувствительным, чем необязательный
    параметр в методе, потому что реляционные значения в РСУБД Обязательно следует отредактировать это в будущем, даже возможно, иногда оно изменится
    снова и снова на базе использования БД.

2 . Может обрабатываться с кодом, который я вам покажу.

Поэтому основываясь на этих объяснениях, вы можете иметь столбец со значением по умолчанию, существующим в Fkeys, но он не будет тем, что вам нужно, и вы должны обновить его в будущем в зависимости от вашего использования. и для этого вам нужно:

ПЕРВОЕ:

  • Создать функцию, которая возвращает действующий и существующий внешний ключ конкретная таблица как это:
CREATE FUNCTION SelectMinForeignKey()
RETURNS INT
AS
BEGIN
  DECLARE @FirstID INT
  SELECT @FirstID = MIN(ID) from DetailTableExample01
  RETURN @FirstID
END

ВТОРОЙ:

  • Затем вы должны изменить свою таблицу, добавив столбец следующим образом:
ALTER TABLE example1 ADD NoNullableCol INT NOT NULL DEFAULT [dbo].SelectMinForeignKey()
  • или с добавлением Relation мгновенно:
  ALTER TABLE example1 
    ADD NoNullableCol2 INT NOT NULL  DEFAULT [dbo].SelectMinForeignKey() ,
    FOREIGN KEY(NoNullableCol2) REFERENCES DetailTableExample01(id);
  • или более в комплекте с мгновенным добавлением ограничения и назначаемым именем FK:
ALTER TABLE dbo.example1 ADD
    NoNullableCol INT NOT NULL  DEFAULT [dbo].SelectMinForeignKey(),
    CONSTRAINT FK_example1_DetailTableExample01
    FOREIGN KEY (NoNullableCol) 
    REFERENCES dbo.DetailTableExample01 (ID) 
     ON UPDATE  CASCADE 
     ON DELETE  CASCADE;
  • или
ALTER TABLE dbo.example1 ADD
    NoNullableCol INT NOT NULL  DEFAULT [dbo].SelectMinForeignKey()
GO
ALTER TABLE dbo.example1 ADD 
    CONSTRAINT FK_example1_DetailTableExample01
    FOREIGN KEY (NoNullableCol) 
    REFERENCES dbo.DetailTableExample01 (ID) 
     ON UPDATE  CASCADE 
     ON DELETE  CASCADE

ПРИМЕЧАНИЕ. Как известно, имена таблиц и столбцов являются примерами.

ТРЕТИЙ:

  • Теперь вам нужно изменить значения в NoNullableCol так, как вы хотите

Все-в-одном:

  • Весь запрос будет выглядеть примерно так
CREATE FUNCTION SelectMinForeignKey()
RETURNS INT
AS
BEGIN
  DECLARE @FirstID INT
  SELECT @FirstID = MIN(ID) from DetailTableExample01
  RETURN @FirstID
END

GO

ALTER TABLE dbo.example1 ADD
    NoNullableCol INT NOT NULL  DEFAULT [dbo].SelectMinForeignKey(),
    CONSTRAINT FK_example1_DetailTableExample01
    FOREIGN KEY (NoNullableCol) 
    REFERENCES dbo.DetailTableExample01 (ID) 
     ON UPDATE  CASCADE 
     ON DELETE  CASCADE;

И готово!

Надеюсь, это решит вашу проблему

...