6

我在将行插入表中的存储过程中有类似于以下的代码,我想将最后一列(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
4

4 回答 4

3

由于本质上这就是 SQL Server 正在做的事情,你可以做这样的事情来至少避免两个几乎相同的语句(伪代码):

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

IF @prmSomeValue IS NOT NULL
    UPDATE ... ;

我认为没有一种方法可以使用默认值进行 COALESCE。

于 2010-03-02T20:58:55.380 回答
2

我会说你的方法很好。一个简单的检查,然后是一个插入。如果您担心 DRY,请将调用封装起来,以便重复调用。

我会说在某些表上插入/更新数据库可能代价高昂(取决于设计目标),所以如果您必须编写额外的代码来处理这种情况,那么我认为权衡没有问题。

于 2010-03-02T21:01:05.650 回答
0

可能有效,取决于您是指在默认约束中定义的默认值,还是在代码中定义的默认值?如果“约束”它失败,如果“代码”它工作。编辑:你的意思是约束。哦!

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 子句中指定列都需要一个值。

所以你的第一个解决方案就是你所做的......

于 2010-03-02T20:55:13.420 回答
0

像这样的东西可能会起作用(虽然不是很漂亮):

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
于 2010-03-02T21:09:13.257 回答