【问题标题】:SQL Server AutoIncrement varying by value of another fieldSQL Server AutoIncrement 因另一个字段的值而异
【发布时间】:2012-08-22 13:53:57
【问题描述】:

使用 SQL Server 2008 R2 我想要一个表(已经在 2 列上具有主键),其中第三列是基于主键的两列之一的自动增量。

换句话说,我希望在向表中添加新记录时,有一个自动增量文件AIfield 自动增量如下:

  PK1 PK2  AIfield 
  ------------------
  1   A     1
  1   B     2
  1   C     3
  2   A     1
  2   B1    2
  2   B2    3
  2   C1    4

其中 PK1 和 PK2 是主键的两个字段。

我不想使用明显的 MAX(Afield)+1 方法,因为我很可能必须为同一个 PK1 进行并发插入 - 这迟早会在 AIfield 中为同一个 PK1 创建重复项。

有什么建议吗?

【问题讨论】:

  • 对每个人来说:问题是没有获得具有唯一编号的选择,使用值更新表的列是并发安全的。因此,仅 SELECT ROW_NUMBER() 的所有答案都不能回答问题

标签: sql-server-2008 auto-increment


【解决方案1】:
select pk1,pk2,ROW_NUMBER() over (partition by pk1,pk2 order by (select 0)) as AIfield
from yourtable

【讨论】:

  • 这是并发插入安全的吗?
  • 你能告诉我更多细节吗?
  • 你可以做的是,把上面的查询结果放到一个表变量或者临时表中,然后做你需要的处理
  • 问题是我可以让客户尝试同时为同一个 PK1 插入不同的记录。这将导致相同的 Row_number() 建议相同的 AIfield,从而创建重复项。它或多或少与 MAX+1 相同。我知道我可能会发布检查和修复重复项的过程,但这不是一个简洁的方法 - 关于此 here 的更多信息
  • 当您查询此表以将数据导出到文本文件时,我猜您可以使用此查询。那时这将起作用。
【解决方案2】:

嗯,一种方法可能是在 PK1 和 AIfield 上创建唯一索引

CREATE UNIQUE NONCLUSTERED INDEX [test] ON [Table] 
(
[AIfield] ASC,
[PK1] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF,  
IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, 
 ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

并处理违反唯一性的行为

DECLARE @inserted BIT=0
DECLARE @AIfield BIGINT
SELECT @AIfield=MAX(AIfield)+1 FROM Table WHERE PK1=@PK1
WHILE @inserted=0
BEGIN
 BEGIN TRY
  INSERT INTO Table(AIfield,PK1,PK2)
  SELECT  @AIfield,@PK1,@PK2
  SET @inserted=1
 END TRY
 BEGIN CATCH
    IF ERROR_NUMBER()=2601
     BEGIN
     SET @AIfield=@AIfield+1
     END
    ELSE SET @inserted=1
 END CATCH
END

我想知道是否有更原生的 SQL 方法,不过

【讨论】:

    【解决方案3】:

    使用下面的查询:

    Select PK1, PK2, ROW_NUMBER() over (partition by PK1 order by PK1, PK2) as AIfield
    From yourtable
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      • 1970-01-01
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多