Sql 当数据库表违反视图上的唯一约束时,在insert时向数据库表行追加一个增量整数
我有一个名为Form的数据库表,其中包含两列Id和UserName 我已经在表上创建了一个视图,该视图包含Id和UserName列 在那个视图上,我为列UserName创建了唯一的聚集索引,所以每当用户尝试为UserName插入重复的值时,它都会抛出唯一的约束冲突异常 有没有办法达到以下要求,Sql 当数据库表违反视图上的唯一约束时,在insert时向数据库表行追加一个增量整数,sql,sql-server,database,cqrs,event-sourcing,Sql,Sql Server,Database,Cqrs,Event Sourcing,我有一个名为Form的数据库表,其中包含两列Id和UserName 我已经在表上创建了一个视图,该视图包含Id和UserName列 在那个视图上,我为列UserName创建了唯一的聚集索引,所以每当用户尝试为UserName插入重复的值时,它都会抛出唯一的约束冲突异常 有没有办法达到以下要求, 我需要附加一个递增的整数以使用户名唯一。 当用户输入表中已经存在的用户名时,它应该向其追加递增的整数 插入用户名时,我们并不总是在末尾加上“1”。 我需要附加一个递增的整数以使用户名唯一 这与复制文件时
我需要附加一个递增的整数以使用户名唯一。 当用户输入表中已经存在的用户名时,它应该向其追加递增的整数 插入用户名时,我们并不总是在末尾加上“1”。
我需要附加一个递增的整数以使用户名唯一
- 这与复制文件时Windows的行为相匹配
- 如果用户插入“Tom”3次,则应创建“tom1”、“Tom” “2”和“汤姆3”
- 如果用户再次插入“Tom”,则应创建“tom4”
- 再想一想:
- 如果用户手动插入“Tom”和“Tom 2”
- 然后用户插入“Tom”-它应该创建“Tom 1”。
然后用户再次插入“Tom”-它应该创建“Tom 3”,因为“Tom 2”已经存在
- 它类似于windows文件目录。当我们在某个文件夹中复制/粘贴文本文档时,它会一遍又一遍地复制/粘贴文本文档
我需要此功能,以便在CQRS中使用EventSourcing实现唯一名称,C#应用程序,其中当用户复制某些实体(例如FormName)时,它只需在Db中存在的FormName的基础上向FormName追加增量整数,并可从Db So返回,我们可以在UI上显示新的FormName。您可以尝试在SQL中的
try…CATCH
块中捕获特定错误,然后编辑要插入的值:
declare @insert bit = 1
declare @uName varchar(20) = 'Tom'
declare @iteration int = 1
WHILE @insert = 1
BEGIN
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO [table](UserName) VALUES
(@uName)
SET @insert = 0
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
SET @insert = 0
IF ERROR_NUMBER() = 2601
BEGIN
IF ISNUMERIC(RIGHT(@uName,1)) = 1
BEGIN
SET @iteration = convert(int,RIGHT(@uName,1)) + 1
SET @uName = LEFT(@uName,LEN(@uName) - 1)
END
SET @uName = @uName + convert(varchar,@iteration)
SET @insert = 1
END
END CATCH
END
要获得要查找的确切错误号(),可以进行测试运行,有意插入一个将违反唯一约束的值,其中CATCH
块为:
BEGIN CATCH
SELECT ERROR_NUMBER()
END CATCH
编辑
正如@Roshan所指出的,这种情况下正确的ERROR\u NUMBER()
这是可以在TRY…CATCH
块内完成的吗?最好在数据库端完全处理,如果不可能,我们可以考虑TRY…CATCH块…在这种情况下,如果Tom1已经存在,它将在每次创建Tom时追加1,如Tom11和Tom111等等:(@Roshan针对此类情况进行了编辑,或者如果您开始尝试手动输入附加用户名,我认为应该是“if ISNUMERIC(RIGHT(@uName,1))=1”,而不是“if ISNUMERIC(RIGHT(@uName,1))=0”。还添加了错误号:)。它工作得很好。非常感谢@Sam@Roshan使用@@tracount
将开始事务
和提交事务
放在TRY
块中,将回滚事务
放在CATCH
中(请参见编辑)