TSQL:获取下一个可用ID

时间:2013-04-11 20:28:38

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

使用SQL Server 2008,有三个表,表a,表b和表c。

所有列都有ID列,但对于表a和b,ID列为identity integer,对于表c,ID列为{{1} } type

当前存储过程采用名称参数,遵循某些逻辑,插入表a或表b,获取标识,前缀为“A”或“B”,然后插入表c。

问题是,表C varchar列可能具有重复值,即如果表A中的标识为2,则{{1}中可能已存在'A2','A3','A5'表C的列,如何编写T-SQL查询以识别表C中的下一个可用值,然后确保相应地更新表A / B?

[更新] 这是当前的步骤, 1.取决于输入参数,插入表A或表B. 2.初始化种子值= @@ Identity 3.通过前缀'A'计算要插入表C的ID值,或者使用种子值附加'B' 4.通过步骤3中的ID值查找表C中的记录匹配,如果没有找到任何记录,插入它,否则将种子值增加1然后重复步骤3

问题在某个值范围内,表C ID中可能存在巨大的价值块,即现在表C ID中存在A3000到A500000,如果遵循现有逻辑,数据库查询会非常慢。需要找出一个逻辑来巧妙地获得最小可用数量(没有前缀)

很难描述,希望这更有意义,我真的很感谢任何帮助,提前谢谢!

2 个答案:

答案 0 :(得分:1)

根据您的设计,考虑到A和B是唯一的,表C中不应有任何重复。

A | B | C
1   1   A1
2   2   A2
        B1
        B2

答案 1 :(得分:1)

这应该可以解决问题。简单的自提取示例将在SSMS中起作用。为了以防万一,我甚至把它弄错了。您只需将表更改为@Data所在的位置,然后更改标识符字段以替换“ID”。

declare @Data Table ( Id varchar(3) );

insert into @Data values ('A5'),('A2'),('B1'),('A3'),('B2'),('A4'),('A1'),('A6');

With a as 
    (
    Select
        ID
    ,   cast(right(Id, len(Id)-1)  as int) as Pos
    ,   left(Id, 1) as TableFrom
    from @Data
    )
select
    TableFrom
,   max(Pos) + 1 as NextNumberUp
from a
group by TableFrom

编辑:如果您不想担心生产数据,可以添加最后一部分来修改我写的内容:

Select
   TableFrom 
,  max(Pos) as LastPos
into #Temp
from a
group by TableFrom

select TableFrom, LastPos + 1
from #Temp

无论这是生产环境,您都必须在某个时间点击它的一部分来获取数据。如果数据集不是太大而且只是varchar(256)或更少且只有500万行或更少,则可以将整个列从tableC转储到临时表。诚实地,查询性能与导入在系统之间的变化很大。