【问题标题】:T-SQL, Insert into with MAX()+1 in subquery doesn't increment, alternatives?T-SQL,在子查询中插入 MAX()+1 不会增加,替代方案?
【发布时间】:2011-08-08 15:42:56
【问题描述】:

我有一个查询,我需要将行“批量”插入到具有没有标识的主键的表中。

--TableA
--PK int (Primary key, no-identity)
--CustNo int
INSERT INTO TableA (PK,CustNo)
  SELECT (SELECT MAX(PK)+1 AS PK FROM TableA), CustNo
  FROM Customers

(简化示例 - 请不要评论可能的并发问题 :-))

问题是它不会为每个已处理的行增加 PK,并且我得到主键违规。

我知道如何使用游标/while 循环来完成,但我想避免这种情况,并以基于集合的方式解决它,如果这可能的话?

(运行 SQL Server 2008 标准版)

【问题讨论】:

  • 为什么不将该列设为标识列?
  • +1 @Cyber​​nate - 这是一个糟糕的主意,如果您费心在 SO 上搜索,大约有 20 个与此类似的问题,每个问题都会告诉您为什么这是一个坏主意。
  • 长话短说:如果可以的话,我会做一个身份:-)。 @JNK我打扰了,但这是我唯一的选择,我想以最好的方式解决它。另请记住,我提供了一个简化的示例。
  • 请详细说明是什么阻止了您使其成为身份。是的,在很多情况下,身份有(更好的)替代方案,但如果没有有效的用途,那么身份一开始就不是一个特征。

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


【解决方案1】:
Declare @i int;

Select @i = max(pk) + 1 from tablea;

INSERT INTO TableA (PK, custno)
Select row_number() over(order by custno) + @i  , CustNo
FROM Customers

【讨论】:

    【解决方案2】:

    +1 给 Michael Buen,但我有一个建议:

    tablea 可以是空的,所以我们应该这样写:

    Select @i = isnull(max(pk),0) + 1 from tablea;
    

    这将防止在尝试使用此代码时出现空错误。

    【讨论】:

      【解决方案3】:

      您看到的问题是它们都获得相同的行号,每行的 max(PK) +1 都是相同的。

      尝试将其转换为Max(PK) + Row_number()

      我正在研究为什么您知道这是一个坏主意等,并且您的问题被简化是为了获得答案,而不是您希望如何解决问题。

      【讨论】:

      【解决方案4】:

      你可以;

      ;with T(NPK, CustNo) as (
        select row_number() over (order by CustNo), CustNo from Customers
      )
      insert into TableA (PK, CustNo)
        select NPK, custno from T
      order by CustNo 
      

      【讨论】:

        【解决方案5】:

        哥们,我有一个建议给你,一个更好的 SQL 实践说使用 SEQUENCE,你猜怎么着,这很容易,只需复制并粘贴我的:

        创建序列 SEQ_TABLEA 作为整数 从 1 开始 增加 1 最大值 2147483647 最小值 1 无循环

        并像这样使用:

        插入表 A (PK,CustNo) 值 (SEQ_TABLEA.NEXTVAL,123)

        希望这篇小贴士能帮到你!

        【讨论】:

        • 感谢您的回答,但最初的问题是关于 SQL Server 2008,而 SEQUENCE 仅适用于 SQL Server 2012+
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        • 2017-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多