Подтвердить что ты не робот

Вставить значение по умолчанию, когда параметр равен нулю

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

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

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

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

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

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

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

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

  • поддерживать значение default в нескольких местах и ​​
  • используйте несколько операторов insert.

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

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

4b9b3361

Ответ 1

Попробуйте оператор if...

if @value is null 
    insert into t (value) values (default)
else
    insert into t (value) values (@value)

Ответ 2

Кристоф,

Значение по умолчанию для столбца применяется только в том случае, если вы не укажете столбец в инструкции INSERT.

Так как вы явно перечисляете столбец в своем заявлении insert, а параметр explicity - NULL, это переопределение значения по умолчанию для этого столбца

Что вам нужно сделать, это "если null передан в ваш sproc, тогда не пытайтесь вставить этот столбец".

Это быстрый и неприятный пример того, как это сделать с помощью какого-либо динамического sql.

Создайте таблицу с несколькими столбцами со значениями по умолчанию...

CREATE TABLE myTable (
    always VARCHAR(50),
    value1 VARCHAR(50) DEFAULT ('defaultcol1'),
    value2 VARCHAR(50) DEFAULT ('defaultcol2'),
    value3 VARCHAR(50) DEFAULT ('defaultcol3')
)

Создайте SPROC, который динамически создает и выполняет инструкцию insert в соответствии с параметрами ввода

ALTER PROCEDURE t_insert (
    @always VARCHAR(50),
    @value1 VARCHAR(50) = NULL,
    @value2 VARCHAR(50) = NULL,
    @value3 VARCAHR(50) = NULL
)
AS 
BEGIN
DECLARE @insertpart VARCHAR(500)
DECLARE @valuepart VARCHAR(500)

SET @insertpart = 'INSERT INTO myTable ('
SET @valuepart = 'VALUES ('

    IF @value1 IS NOT NULL
    BEGIN
        SET @insertpart = @insertpart + 'value1,'
        SET @valuepart = @valuepart + '''' + @value1 + ''', '
    END

    IF @value2 IS NOT NULL
    BEGIN
        SET @insertpart = @insertpart + 'value2,'
        SET @valuepart = @valuepart + '''' + @value2 + ''', '
    END

    IF @value3 IS NOT NULL
    BEGIN
        SET @insertpart = @insertpart + 'value3,'
        SET @valuepart = @valuepart + '''' + @value3 + ''', '
    END

    SET @insertpart = @insertpart + 'always) '
    SET @valuepart = @valuepart + + '''' + @always + ''')'

--print @insertpart + @valuepart
EXEC (@insertpart + @valuepart)
END

Следующие 2 команды должны дать вам пример того, что вы хотите в качестве выходов...

EXEC t_insert 'alwaysvalue'
SELECT * FROM  myTable

EXEC t_insert 'alwaysvalue', 'val1'
SELECT * FROM  myTable

EXEC t_insert 'alwaysvalue', 'val1', 'val2', 'val3'
SELECT * FROM  myTable

Я знаю, что это очень запутанный способ делать то, что вам нужно. Вы, вероятно, могли бы одинаково выбрать значение по умолчанию из InformationSchema для соответствующих столбцов, но, честно говоря, я мог бы просто добавить значение по умолчанию к параметру в верхней части процедуры.

Ответ 3

Насколько мне известно, значение по умолчанию вводится только тогда, когда вы не указываете значение в инструкции insert. Так, например, вам нужно сделать что-то вроде следующего в таблице с тремя полями (значение 2 по умолчанию)

INSERT INTO t (value1, value3) VALUES ('value1', 'value3')

И тогда значение2 будет дефолтным. Может быть, кто-то заговорит о том, как это сделать для таблицы с одним полем.

Ответ 4

Вероятно, это не самый эффективный способ, но вы можете создать скалярную функцию, которая извлекает из информационной схемы имя таблицы и столбца, а затем вызывает это с использованием ранее используемой логики isnull:

    CREATE FUNCTION GetDefaultValue
    (
        @TableName VARCHAR(200),
        @ColumnName VARCHAR(200)
    )
    RETURNS VARCHAR(200)
    AS
    BEGIN
        -- you'd probably want to have different functions for different data types if
        -- you go this route
    RETURN (SELECT TOP 1 REPLACE(REPLACE(REPLACE(COLUMN_DEFAULT, '(', ''), ')', ''), '''', '') 
            FROM information_schema.columns
            WHERE table_name = @TableName AND column_name = @ColumnName)

    END
    GO

И затем назовите его следующим образом:

INSERT INTO t (value) VALUES ( ISNULL(@value, SELECT dbo.GetDefaultValue('t', 'value') )

Ответ 5

Это лучшее, что я могу придумать. Это предотвращает внедрение SQL-запросов только одним инструктором insert и может быть расширено с помощью дополнительных операторов case.

CREATE PROCEDURE t_insert (     @value varchar(50) = null )
as
DECLARE @sQuery NVARCHAR (MAX);
SET @sQuery = N'
insert into __t (value) values ( '+
CASE WHEN @value IS NULL THEN ' default ' ELSE ' @value ' END +' );';

EXEC sp_executesql 
@stmt = @sQuery, 
@params = N'@value varchar(50)',
@value = @value;

GO

Ответ 6

chrisofspades,

Насколько я знаю, это поведение несовместимо с тем, как работает движок db, но есть простое (я не знаю, элегантно ли, но результативно) решение для достижения двух целей НЕ НЕ

  • сохранить значение по умолчанию в нескольких местах и ​​
  • использовать несколько операторов вставки.

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

CREATE TABLE t (
    insValue VARCHAR(50) NULL
    , selValue AS ISNULL(insValue, 'something')
)

DECLARE @d VARCHAR(10)
INSERT INTO t (insValue) VALUES (@d) -- null
SELECT selValue FROM t

Этот метод позволяет вам централизовать управление бизнес-значениями по умолчанию в таблице параметров, для чего это делает специальная функция, изменение vg:

selValue AS ISNULL(insValue, 'something')

для

selValue AS ISNULL(insValue, **getDef(t,1)**)

Надеюсь, это поможет.

Ответ 7

Вы можете использовать значения по умолчанию для параметров хранимых процедур:

CREATE PROCEDURE MyTestProcedure ( @MyParam1 INT,
@MyParam2 VARCHAR(20) = ‘ABC’,
@MyParam3 INT = NULL)
AS
BEGIN
    -- Procedure body here

END

Если @MyParam2 не указан, он будет иметь значение "ABC"...

Ответ 8

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

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

Ответ 9

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

INSERT INTO t (значение) ЦЕННОСТИ (COALESCE (@value, 'something'))

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

Мое предпочтение было бы предложением Mitchel Sellers, но это не работает в MS SQL. Невозможно говорить с другими SQL-dbms.

Ответ 10

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

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

`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 - это столбец фотографий, который хранится в виде массива байтов. - И я планировал использовать фотографию по умолчанию, когда фотографии нет. --to sp для хранения в db..

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`

Ответ 11

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

INSERT t DEFAULT VALUES

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

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

Ответ 12

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

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

Ответ 13

Лучшим вариантом является создание триггера INSTEAD OF INSERT для вашей таблицы, удаление значений по умолчанию из вашей таблицы и перемещение их в триггер.

Это будет выглядеть следующим образом:

create trigger dbo.OnInsertIntoT
ON TablenameT
INSTEAD OF INSERT
AS
insert into TablenameT
select
   IsNull(column1 ,<default_value>)
  ,IsNull(column2 ,<default_value>)
  ...
from inserted

Это заставляет работать NO MATTER, какой код пытается вставить NULL в вашу таблицу, избегает хранимых процедур, полностью прозрачен, и вам нужно только поддерживать значения по умолчанию в одном месте, а именно этот триггер.

Ответ 14

Шаблон, который я обычно использую, состоит в том, чтобы создать строку без столбцов, которые имеют ограничения по умолчанию, а затем обновить столбцы, чтобы заменить значения по умолчанию предоставленными значениями (если не ноль).

Предполагая, что col1 является первичным ключом, а col4 и col5 имеют стандартное ограничение

-- create initial row with default values
insert table1 (col1, col2, col3)
    values (@col1, @col2, @col3)

-- update default values, if supplied
update table1
    set col4 = isnull(@col4, col4),
        col5 = isnull(@col5, col5)
    where col1 = @col1

Если вы хотите фактические значения по умолчанию в таблице...

-- create initial row with default values
insert table1 (col1, col2, col3)
    values (@col1, @col2, @col3)

-- create a container to hold the values actually inserted into the table
declare @inserted table (col4 datetime, col5 varchar(50))

-- update default values, if supplied
update table1
    set col4 = isnull(@col4, col4),
        col5 = isnull(@col5, col5)
    output inserted.col4, inserted.col5 into @inserted (col4, col5)
    where col1 = @col1

-- get the values defaulted into the table (optional)
select @col4 = col4, @col5 = col5 from @inserted

Приветствия...

Ответ 15

Таблица Аджунто. Процедура вставки Изъятие: проверка по умолчанию DEFAULT en el paso al SP.

Итоговое окончательное постановление о дефектах, окончательное указание по SP. Misma técnica si no se quiere usar el SP y hacer el ЗНАЧЕНИЯ INSERT (CAMPOS) (по умолчанию) Ver default по умолчанию, отличая от 'default' (con comillas)

    create Table Cliente_SeguimientoDeuda(IDRegistro int identity(1,1), Cliente int, ReferenciaReclamacion NVarChar(20) Default 'Reclamación', 
    Fecha DateTime, PersonaContactada nvarchar(30), Causa NVarChar(50), CompromisoObtenido NvarChar(50), 
    Usuario NVarChar(50), NotasReclamacion NVarChar(500),
    Primary Key (IDRegistro))


    create procedure NET_ADDReclamacion(@Cliente int, @ReferenciaReclamacion nvarchar(20)='por defecto' , 
    @Fecha datetime, @PersonaContactada nvarchar(30),@Causa nvarchar(50), @Compromiso nvarchar(50)
    , @Usuario nvarchar(50), @NotasReclamacion nvarchar(500))
    as
    set nocount on
    insert into Cliente_SeguimientoDeuda(Cliente, ReferenciaReclamacion,Fecha, PersonaContactada,Causa,CompromisoObtenido,
    Usuario, NotasReclamacion) Values (@Cliente,@ReferenciaReclamacion,@Fecha,@PersonaContactada,@Causa,@Compromiso,
    @Usuario,@NotasReclamacion)
    select @@IDENTITY

NET_ADDReclamacion 1,default,'01-01-2019','roberto','causa','compromiso','usu','notas'

Ответ 16

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

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

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

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

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

Ответ 17

Вопросник должен узнать разницу между пустым значением и значением null.

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

.