Вставьте значение по умолчанию, когда параметр имеет значение NULL - PullRequest
39 голосов
/ 23 октября 2008

У меня есть таблица со столбцом со значением по умолчанию:

create table t (
    value varchar(50) default ('something')
)

Я использую хранимую процедуру для вставки значений в эту таблицу:

create procedure t_insert (
    @value varchar(50) = null
)
as 
insert into t (value) values (@value)

Вопрос в том, как заставить его использовать значение по умолчанию, когда @value равно null? Я попробовал:

insert into t (value) values ( isnull(@value, default) )

Это явно не сработало. Также попробовал оператор case, но это тоже не очень хорошо. Любые другие предложения? Я поступаю неправильно?

Обновление: я пытаюсь выполнить это без необходимости:

  1. поддерживает значение default в нескольких местах, а
  2. использовать несколько insert операторов.

Если это невозможно, я думаю, мне просто придется с этим смириться. Просто кажется, что-то такое должно быть достижимо.

Примечание. Моя таблица содержит более одного столбца. Я просто быстро написал пример.

Ответы [ 17 ]

0 голосов
/ 25 февраля 2016

Самым кратким решением, которое я мог придумать, является добавление вставки с обновлением для столбца по умолчанию:

IF OBJECT_ID('tempdb..#mytest') IS NOT NULL DROP TABLE #mytest
CREATE TABLE #mytest(f1 INT DEFAULT(1), f2 INT)
INSERT INTO  #mytest(f1,f2) VALUES (NULL,2)
INSERT INTO  #mytest(f1,f2) VALUES (3,3)

UPDATE #mytest SET f1 = DEFAULT WHERE f1 IS NULL

SELECT * FROM #mytest
0 голосов
/ 31 мая 2012

Если на столе достаточно значений по умолчанию, вы можете просто сказать:

INSERT t DEFAULT VALUES

Обратите внимание, что это довольно маловероятный случай, однако.

Мне приходилось использовать его только один раз в производственной среде. У нас было две тесно связанные таблицы, и нам нужно было гарантировать, что ни одна из таблиц не имела одинакового UniqueID, поэтому у нас была отдельная таблица, в которой был только столбец идентификаторов, и лучший способ вставить в нее был с синтаксисом выше.

0 голосов
/ 20 февраля 2012

Надеюсь помочь -newbie, как я, кто использует операторы Upsert в MSSQL .. (Этот код, который я использовал в своем проекте на MSSQL 2008 R2 и работает просто отлично. Может быть, это не лучшая практика. Время выполнения статистика показывает время выполнения в 15 миллисекунд с оператором вставки)

Просто установите поле «Значение по умолчанию или столбец» для вашего столбца как то, что вы решили использовать в качестве значения по умолчанию для своего столбца, а также установите для столбца значение Не принимать нулевые значения из меню дизайна и создайте этот сохраненный процесс.

`USE [YourTable]
GO


SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROC [dbo].[YourTableName]

    @Value smallint,
    @Value1 bigint,
    @Value2 varchar(50),
    @Value3 varchar(20),
    @Value4 varchar(20),
    @Value5 date,
    @Value6 varchar(50),
    @Value7 tinyint,
    @Value8 tinyint,
    @Value9 varchar(20),
    @Value10 varchar(20),
    @Value11 varchar(250),
    @Value12 tinyint,
    @Value13 varbinary(max) 

- в моем проекте @ Value13 - столбец фотографий, который хранится в виде байтового массива. - И я планировал использовать фотографию по умолчанию, когда не было передано ни одной фотографии - чтобы хранить в дб ..

AS
--SET NOCOUNT ON
IF @Value = 0 BEGIN
    INSERT INTO YourTableName (
        [TableColumn1],
        [TableColumn2],
        [TableColumn3],
        [TableColumn4],
        [TableColumn5],
        [TableColumn6],
        [TableColumn7],
        [TableColumn8],
        [TableColumn9],
        [TableColumn10],
        [TableColumn11],
        [TableColumn12],
        [TableColumn13]
    )
    VALUES (
        @Value1,
        @Value2,
        @Value3,
        @Value4,
        @Value5,
        @Value6,
        @Value7,
        @Value8,
        @Value9,
        @Value10,
        @Value11,
        @Value12,
        default
    )
    SELECT SCOPE_IDENTITY() As InsertedID
END
ELSE BEGIN
    UPDATE YourTableName SET 
        [TableColumn1] = @Value1,
        [TableColumn2] = @Value2,
        [TableColumn3] = @Value3,
        [TableColumn4] = @Value4,
        [TableColumn5] = @Value5,
        [TableColumn6] = @Value6,
        [TableColumn7] = @Value7,
        [TableColumn8] = @Value8,
        [TableColumn9] = @Value9,
        [TableColumn10] = @Value10,
        [TableColumn11] = @Value11,
        [TableColumn12] = @Value12,
        [TableColumn13] = @Value13
    WHERE [TableColumn] = @Value

END
GO`
0 голосов
/ 24 октября 2008

Вы можете использовать функцию COALESCE в MS SQL.

INSERT INTO t (значение) VALUES (COALESCE (@value, 'нечто'))

Лично я не в восторге от этого решения, потому что это кошмар обслуживания, если вы хотите изменить значение по умолчанию.

Я бы предпочел предложение Митчела Селлерса, но в MS SQL это не работает. Не может общаться с другими базами данных SQL.

0 голосов
/ 24 октября 2008

Опрашивающему необходимо узнать разницу между предоставленным пустым значением и нулем.

Другие опубликовали правильный базовый ответ: предоставленное значение, включая ноль, равно что-то , и поэтому оно используется. Значение по умолчанию ТОЛЬКО предоставляет значение, если ничего не указано. Но настоящая проблема здесь - непонимание значения нуля.

.

0 голосов
/ 23 октября 2008

Не указывайте столбец или значение при вставке, а значение содержимого DEFAULT будет заменено отсутствующим значением.

Я не знаю, как это будет работать в таблице с одним столбцом. Я имею в виду: это было бы, но это не было бы очень полезно.

0 голосов
/ 23 октября 2008

Самый простой способ сделать это - изменить объявление таблицы на

CREATE TABLE Demo
(
    MyColumn VARCHAR(10) NOT NULL DEFAULT 'Me'
)

Теперь в вашей хранимой процедуре вы можете сделать что-то вроде.

CREATE PROCEDURE InsertDemo
    @MyColumn VARCHAR(10) = null
AS
INSERT INTO Demo (MyColumn) VALUES(@MyColumn)

Однако этот метод работает ТОЛЬКО если у вас не может быть нулевого значения, в противном случае вашей хранимой процедуре придется использовать другую форму вставки для запуска значения по умолчанию.

...