Insert default value when parameter is null

后端 未结 16 1973
遥遥无期
遥遥无期 2020-12-24 05:27

I have a table that has a column with a default value:

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

I\'m using a stored

相关标签:
16条回答
  • 2020-12-24 05:55

    As far as I know, the default value is only inserted when you don't specify a value in the insert statement. So, for example, you'd need to do something like the following in a table with three fields (value2 being defaulted)

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

    And then value2 would be defaulted. Maybe someone will chime in on how to accomplish this for a table with a single field.

    0 讨论(0)
  • 2020-12-24 05:55

    Probably not the most performance friendly way, but you could create a scalar function that pulls from the information schema with the table and column name, and then call that using the isnull logic you tried earlier:

        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
    

    And then call it like this:

    INSERT INTO t (value) VALUES ( ISNULL(@value, SELECT dbo.GetDefaultValue('t', 'value') )
    
    0 讨论(0)
  • 2020-12-24 05:56

    Christophe,

    The default value on a column is only applied if you don't specify the column in the INSERT statement.

    Since you're explicitiy listing the column in your insert statement, and explicity setting it to NULL, that's overriding the default value for that column

    What you need to do is "if a null is passed into your sproc then don't attempt to insert for that column".

    This is a quick and nasty example of how to do that with some dynamic sql.

    Create a table with some columns with default values...

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

    Create a SPROC that dynamically builds and executes your insert statement based on input params

    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
    

    The following 2 commands should give you an example of what you want as your outputs...

    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
    

    I know this is a very convoluted way of doing what you need to do. You could probably equally select the default value from the InformationSchema for the relevant columns but to be honest, I might consider just adding the default value to param at the top of the procedure

    0 讨论(0)
  • 2020-12-24 05:56

    The most succinct solution I could come up with is to follow the insert with an update for the column with the default:

    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 讨论(0)
  • 2020-12-24 05:58

    The questioner needs to learn the difference between an empty value provided and null.

    Others have posted the right basic answer: A provided value, including a null, is something and therefore it's used. Default ONLY provides a value when none is provided. But the real problem here is lack of understanding of the value of null.

    .

    0 讨论(0)
  • 2020-12-24 05:59

    You can use the COALESCE function in MS SQL.

    INSERT INTO t ( value ) VALUES( COALESCE(@value, 'something') )

    Personally, I'm not crazy about this solution as it is a maintenance nightmare if you want to change the default value.

    My preference would be Mitchel Sellers proposal, but that doesn't work in MS SQL. Can't speak to other SQL dbms.

    0 讨论(0)
提交回复
热议问题