【问题标题】:Write INSERT statements with values next to column names?用列名旁边的值编写 INSERT 语句?
【发布时间】:2011-01-04 15:03:53
【问题描述】:

在编写包含大量列的 INSERT 语句时,最好将值放在列名旁边,就像在 UPDATE 语句中一样。比如:

insert into myTable
set
  [col1] = 'xxx',
  [col2] = 'yyy',
  [col3] = 42
  etc...

有什么技巧可以模仿吗?

我以为我对此有所了解:

insert into myTable
select
  [col1] = 'xxx',
  [col2] = 'yyy',
  [col3] = 42
  etc...

但是别名实际上并没有与插入表的列相关联,如果有人向表中添加了一个新列,它可能真的搞砸了。有人对如何做到这一点有任何其他想法吗?

【问题讨论】:

  • 这是 SQL 真正的烦恼之一。并且它会导致错误,因为很容易意外更改订单,并且如果数据类型兼容,您会突然将电话号码放入电子邮件列而没有错误。
  • 我也非常希望 SQL 提供了一种方法来做到这一点。它将显着提高可读性。

标签: sql sql-server tsql sql-server-2008 insert


【解决方案1】:

您将得到的最接近的方法是在插入时指定列(这将避免您担心要添加新列)并为选择上的值设置别名(这为您提供了一定程度的自我记录代码)。

insert into myTable
    ([col1], [col2], [col3])
    select 'xxx' as [col1], 'yyy' as [col2], 42 as [col3]

【讨论】:

  • 别名不是必需的,假设选择顺序与进入列顺序匹配。尽管它们可能有助于清楚地表明事情。 :)
  • @Rocky Madden:同意。正如我在回答中所指出的那样,我更多地包含了别名作为对代码进行自我记录的尝试。
  • 只是想确保 OP 清楚这一点。像往常一样,你的钱是对的!
【解决方案2】:

对于大插页,我做了花哨的(也许是过于挑剔的)布局。一些例子:

INSERT MyTable ( MyTableId,        Name,             Description,      SomeStringData1
                ,SomeStringData2,  SomeStringData3,  SomeStringData4,  MoreStringData1
                ,MoreStringData2,  MoreStringData3,  MoreStringData4,  SomeNumericData1
                ,SomeNumericData2, SomeNumericData3, SomeNumericData4, MoreNumericData1
                ,MoreNumericData2, MoreNumericData3, MoreNumericData4, BigBlobAA
                ,BigBlobBB,        EnteredAtDate,    UpdatedAtDate,    RevisedAtDate
                ,NeedAnotherDate )
 values
               ( @MyTableId,        @Name,             @Description,      @SomeStringData1
                ,@SomeStringData2,  @SomeStringData3,  @SomeStringData4,  @MoreStringData1
                ,@MoreStringData2,  @MoreStringData3,  @MoreStringData4,  @SomeNumericData1
                ,@SomeNumericData2, @SomeNumericData3, @SomeNumericData4, @MoreNumericData1
                ,@MoreNumericData2, @MoreNumericData3, @MoreNumericData4, @BigBlobAA
                ,@BigBlobBB,        @EnteredAtDate,    @UpdatedAtDate,    @RevisedAtDate
                ,@NeedAnotherDate )

如果您非常确定您永远不会插入列或以其他方式修改正在插入的内容,则此方法有效。它可以在一个屏幕上获取所有内容,并且可以非常简单地选择哪个值进入哪一列。

如果插入的值可能会更改或很复杂(例如 case 语句),我会执行以下操作(除每 5 个项目外,所有项目都被淘汰):

INSERT MyTable
  (
     MyTableId
    ,Name
    ,Description
    ,SomeStringData1
   ,SomeStringData2
    ,SomeStringData3
    ,SomeStringData4
    ,MoreStringData1
    ,MoreStringData2
   ,MoreStringData3
    ,MoreStringData4
    ,SomeNumericData1
    ,SomeNumericData2
    ,SomeNumericData3
   ,SomeNumericData4
    ,MoreNumericData1
    ,MoreNumericData2
    ,MoreNumericData3
    ,MoreNumericData4
   ,BigBlobAA
    ,BigBlobBB
    ,EnteredAtDate
    ,UpdatedAtDate
    ,RevisedAtDate
   ,NeedAnotherDate
  )
 values
  (
     MyTableId
    ,Name
    ,Description
    ,SomeStringData1
   ,SomeStringData2
    ,SomeStringData3
    ,SomeStringData4
    ,MoreStringData1
    ,MoreStringData2
   ,MoreStringData3
    ,MoreStringData4
    ,case
       when something then 'A'
       when orOther   then 'B'
       else 'Z'
     end
    ,SomeNumericData2
   ,SomeNumericData3
    ,SomeNumericData4
    ,MoreNumericData1
    ,MoreNumericData2
    ,MoreNumericData3
   ,MoreNumericData4
    ,BigBlobAA
    ,BigBlobBB
    ,EnteredAtDate
    ,UpdatedAtDate
   ,RevisedAtDate
    ,NeedAnotherDate
  )

(添加 CASE 语句后,我“计算了缩进数”以确保所有内容都正确排列。)

将事物正确布局需要一些努力,但它可以使维护、支持和后续修改更简单。

【讨论】:

  • 我个人支持你,如果我有很多列,我会将第三或第四列排成一行,并使 selct 或 values 子句的行完全匹配。我仍然需要手动检查,但至少在第一个示例中正确排列列时会更容易。
【解决方案3】:

基本上没有。 SQL INSERT 的语法是列出所有列,然后列出所有值。即使您可以找到一种技巧来按照您想要的方式表达语法,它也是不可移植的,并且会让下一个必须维护您的代码的人感到困惑。

如果您想要列到值的可视化映射,请使用上面 Philip 的回答。但请不要花费任何宝贵的时间让您的代码避免使用标准语法。

【讨论】:

  • 好点子,我有时会想办法让自己变得更好,但绝不应该这样做,这样做的副作用是使我的代码不可读或混乱。
  • 我很欣赏你来自哪里,而且我经常像 Philip 建议的那样做布局(除了我尝试保持在一行上,因此值直接位于列名下方,即使该行非常,很长)。
【解决方案4】:

如果您想同时插入多行,使用 2008 样式的行构造函数,或使用较旧的 union all 语法,您往往会庆幸不必指定列每行的名称。

2008 行构造函数:

insert into myTable (col1,col2,col3)
values ('xxx','yyy',42),
('abc','def',19),
('HJK','www',-4)

联合所有:

insert into myTable (col1,col2,col3)
select 'xxx','yyy',42 union all
select 'abc','def',19 union all
select 'HJK','www',-4

【讨论】:

  • 是的,如果您要插入多行,我可以看到不需要列名,但我指的是插入包含大量列的单行。
【解决方案5】:

我想出的快速解决方案如下:

insert into MyTable
(ColumnName1, ColumnName2, ColumnName3)
values
(/*ColumnName1*/'value1', /*ColumnName2*/'value2', /*ColumnName3*/'value3')

【讨论】:

    【解决方案6】:
    
    INSERT INTO myTable (col1, col2, col3)
     SELECT 'xxx' [col1], 'yyy' [col2], '42' [col3]

    【讨论】:

    • 这和我给出的例子一样。我不希望这样,因为如果有人向 myTable 添加一列,它可能会将数据插入到错误的列中。
    • 您在任何情况下都不应在未指定插入中的列的情况下进行插入。这是糟糕的糟糕代码。
    猜你喜欢
    • 2012-10-18
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    相关资源
    最近更新 更多