У меня есть код, подобный следующему в хранимой процедуре, которая вставляет строку в таблицу, я хотел бы установить последний столбец (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 ... ;
Я не думаю, что есть способ COALESCE со значением по умолчанию.
Я бы сказал, что ваш метод в порядке. Простая проверка, за которой следует одна вставка. Если вас беспокоит 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