方案
我想通过提取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。如何确保一次只能运行此方法的单个实例?
答案 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
这将为您提供此表中用户的最后一个条目,您可以将其用作唯一的整数键
优点:
缺点:一张额外的桌子
额外的表几乎不会占用您数据库中的任何空间,并且任何旧系统都不会受到这个新表的影响。新系统可能会抱怨该表不应该存在,当然这需要进行测试。