使用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,如果遵循现有逻辑,数据库查询会非常慢。需要找出一个逻辑来巧妙地获得最小可用数量(没有前缀)
很难描述,希望这更有意义,我真的很感谢任何帮助,提前谢谢!
答案 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转储到临时表。诚实地,查询性能与导入在系统之间的变化很大。