Есть ли способ условно использовать значения столбцов по умолчанию в инструкции INSERT..SELECT?
-
23-09-2019 - |
Вопрос
У меня есть код, аналогичный следующему, в хранимой процедуре, которая вставляет строку в таблицу. Я бы хотел установить для последнего столбца (FieldD) значение @prmSomeValue, если оно не равно нулю, в противном случае просто используйте значение по умолчанию, определенное для этого. столбец.
IF (@prmSomeValue IS NULL)
INSERT INTO MyTable (fieldA,FieldB,FieldC)
SELECT A,B,C
FROM MyOtherTable
ELSE
INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)
SELECT A,B,C,@prmSomeValue
FROM MyOtherTable
Это работает, но нарушает принцип DRY.Я пытаюсь найти способ сделать это с помощью одного оператора вставки.Что-то вроде следующего псевдокода.
INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)
SELECT A,B,C,ISNULL(@prmSomeValue,DEFAULT)
FROM MyOtherTable
У кого-нибудь есть идеи?
Обновление: еще один поворот
Ограничение по умолчанию — это не буквальное значение, а функция, как показано ниже.
...DEFAULT (suser_sname()) FOR [FieldD]
Обновлять
В конце концов я выбрал меньшее из зол и просто скопировал функцию значения по умолчанию в свой запрос вместо того, чтобы перейти к значению по умолчанию, настроенному для столбца.Мне это не нравится, но он выполняет свою работу с меньшим количеством повторений в моем запросе.
INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)
SELECT A,B,C,ISNULL(@prmSomeValue,suser_sname())
FROM MyOtherTable
Решение
Поскольку, по сути, это то, что делает SQL Server, вы можете сделать что-то вроде этого, чтобы избежать двух почти идентичных операторов (псевдокода):
INSERT (columnA,B,C) ... ;
IF @prmSomeValue IS NOT NULL
UPDATE ... ;
Я не думаю, что есть способ ОБЪЕДИНИТЬСЯ со значением по умолчанию.
Другие советы
Я бы сказал, что ваш метод хорош.Простая проверка, за которой следует одна вставка.Если вас беспокоит DRY, инкапсулируйте вызов, чтобы он вызывался повторно.
Я бы сказал, что вставки/обновления в базу данных могут быть дорогостоящими в некоторых таблицах (зависит от цели проектирования), поэтому, если вам придется написать дополнительный код для обработки этого сценария, я не вижу проблем с компромиссом.
Этот мощь работает, зависит от того, имеете ли вы в виду значение по умолчанию, определенное в ограничении по умолчанию или в коде?Если «ограничение» не работает, если «код» — работает. Редактировать:ты имеешь в виду ограничение.да!
SELECT A,B,C,@prmSomeValue
FROM MyOtherTable
WHERE @prmSomeValue IS NOT NULL
UNION ALL
SELECT A,B,C,DEFAULT
FROM MyOtherTable
WHERE @prmSomeValue IS NULL
Каким бы способом вы ни хотели это сделать, для указания столбца в предложении INSERT требуется значение.
Итак, ваше первое решение - это то, что вам нужно сделать...
Что-то вроде этого может сработать (хотя и не очень красиво):
INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)
SELECT A,B,C,
case when @prmSomeValue is null
then
(SELECT text FROM syscomments WHERE id IN (SELECT cdefault FROM syscolumns
WHERE id = object_id('MyTable') AND cdefault > 0))
else @prmSomeValue
end
FROM MyOtherTable