如何在多用户应用程序中生成整数唯一ID而无需在C#/ SqlServer中重复?

时间:2016-08-22 17:12:27

标签: c# sql-server

方案

我想通过提取max()并将其递增1来生成唯一的整数键(不是数据库主键)。然后我想在一个或多个表中使用该整数键进行插入/更新操作。我更喜欢在C#代码中执行此操作,但如果没有其他选项,那么我也可以使用SQL批处理语句或存储过程等。

问题

由于多个用户可以同时执行此操作,因此如何确保没有两个用户获得相同的max()?

示例伪代码 我们假设有两个表 - Employee(列:EmpId,BatchId,Name)和MiscData(列:EmpId,BatchId)。

下面是C#启发的伪代码,它显示了这种情况的一种实现 -

void DoOperation(int empId, string[] names)
{
    int maxBatchId = repository.GetMaxBatchId(); //GetMaxBatchId() basically executes select max(BatchId) from Employee
    maxBatchId++;
    foreach(string name in names)
        command.ExecuteNonQuery("insert into Employee values (" + maxBatchId + ", '" + name + "')");
    command.ExecuteNonQuery("insert into MiscData select EmpId, " + maxBatchId + " where EmpId = " + empId);
}

上面的DoOperation方法可以根据maxBatchId + 1的值进行任何数据库操作。

如果多个用户同时运行DoOperation(...),他们可能会获得完全相同的maxBatchId。如何确保一次只能运行此方法的单个实例?

2 个答案:

答案 0 :(得分:1)

您可以在SQL Server中使用序列

CREATE SEQUENCE testseq  
START WITH 1  
INCREMENT BY 1 ;  

SELECT NEXT VALUE FOR testseq

答案 1 :(得分:0)

我无法在 SQL Server 中使用序列,因为由于监管规则,我不能在数字中出现间隙。

这是一篇旧帖子,但在我阅读这篇文章以寻找答案时,我想到了一种可能实际可行的不同方法,并将其发布在这里以帮助他人。

如果您在表中创建一个新列并在保存记录时将标识插​​入设置为 true 和 1,1,它将是唯一的。

但是您可能无法修改数据库表,因为它可能会影响其他区域...

所以你可以做的是创建一个包含三个字段的新表:ID、用户名、当前日期时间。

ID 字段递增(1,1)

当您想要一个唯一 ID 时,只需在该表中添加一条记录,其中包含当前日期和时间以及用户名,这将为您生成一个唯一 ID,您就可以

选择 Top 1 ID where UserName = XXX order by DateTime Desc

这将为您提供此表中用户的最后一个条目,您可以将其用作唯一的整数键

优点:

  1. 在多用户中永远不会重复的唯一标识符 环境
  2. 如果您已经创建了记录,则可以插入它们 事后进入此表并开始使用此方法。

缺点:一张额外的桌子

额外的表几乎不会占用您数据库中的任何空间,并且任何旧系统都不会受到这个新表的影响。新系统可能会抱怨该表不应该存在,当然这需要进行测试。