문제

I've got code similar to the following in a stored procedure that inserts a row into a table, I'd like to set the last column (FieldD) to @prmSomeValue unless it is null, otherwise just use the default value defined for that column.

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

This works, but violates the DRY principle. I'm trying to find some way to do this with a single insert statement. Something along the lines of the following pseudocode.

   INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)  
      SELECT A,B,C,ISNULL(@prmSomeValue,DEFAULT)
      FROM MyOtherTable

Anyone have any ideas?

Update - One more twist
The default constraint is not a literal value, but a function as shown below.

...DEFAULT (suser_sname()) FOR [FieldD]

Update
I finally punted and chose the lesser of evils and just copied the default value function into my query instead of falling through to the default configured for the column. I don't love it, but it gets the job done with less repetition in my query.

   INSERT INTO MyTable (fieldA,FieldB,FieldC,FieldD)  
      SELECT A,B,C,ISNULL(@prmSomeValue,suser_sname())
      FROM MyOtherTable
도움이 되었습니까?

해결책

Since essentially this is what SQL Server is doing, you could do something like this to at least avoid two nearly identical statements (pseudo-code):

INSERT (columnA,B,C) ... ;

IF @prmSomeValue IS NOT NULL
    UPDATE ... ;

I don't think there is a way to COALESCE with the default value.

다른 팁

I would say your method is fine. A simple check followed by one insert. If you are worried about DRY, encapsulate the call so that it be called repeatedly.

I would say that inserts/updates on a db may be costly on some tables (depends on the design goal) so if you have to write extra code to to handle this scenario then I see no problem with the trade off.

This might work, depends on if you mean the default value defined in a default constraint, or in code? If "constraint" it fails, if "code" it works. Edit: you mean constraint. doh!

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

Which ever way you want to do it, specifying a column in the INSERT clause requires a value.

So your first solution is what you have do...

Something like this might work (tho not very pretty):

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