Есть ли способ условно использовать значения столбцов по умолчанию в инструкции INSERT..SELECT?

StackOverflow https://stackoverflow.com/questions/2366580

Вопрос

У меня есть код, аналогичный следующему, в хранимой процедуре, которая вставляет строку в таблицу. Я бы хотел установить для последнего столбца (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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top