在违反 View 的唯一约束时插入时将增量整数附加到数据库 table 行
Append an incremental integer to database table row while insert when it is violating unique constraint on View
我有一个名为 Form 的数据库 table,其中包含 2 列 Id 和 UserName。
我在 table 上创建了视图,其中包含列 Id 和 UserName。
在该视图中,我为列 UserName 创建了 UNIQUE CLUSTERED INDEX 因此,每当用户尝试为 UserName 插入重复值时,它都会抛出违反唯一约束的异常。
有什么办法可以达到下面的要求,
我需要附加一个递增的整数以使用户名唯一。
当用户输入 table 中已经存在的用户名时,它应该向其附加递增的整数。
插入用户名时,我们并不总是只在末尾附加一个“1”。
我需要附加一个递增的整数以使 UserName 唯一。
这与复制文件时 Windows 的行为相匹配。
如果用户插入"Tom" 3次,那么它应该创建"Tom 1", "Tom
2" 和 "Tom 3".
如果用户再次插入"Tom",那么它应该创建"Tom 4"。
再想想这个:
如果用户手动插入 "Tom" 和 "Tom 2"
用户然后插入 "Tom" - 它应该创建 "Tom 1".
用户然后再次插入 "Tom" - 它应该创建 "Tom 3" 因为 "Tom 2" 已经存在。
其类似windows文件目录。当我们在某个文件夹中 copy/pasting 文本文档时,它一遍又一遍。
我需要此功能来使用 EventSourcing 在 CQRS 中实现唯一名称,C# 应用程序,当用户复制某些实体时,例如。 FormName 它应该只是根据 Db 中存在的 FormNames 将增量整数附加到 FormName,并且可以 return 来自 db 所以,我们可以在 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
要获得您正在寻找的确切 ERROR_NUMBER(),您可以进行测试 运行,故意插入一个违反唯一约束的值,其中您的 CATCH
块是:
BEGIN CATCH
SELECT ERROR_NUMBER()
END CATCH
编辑
正如@Roshan 指出的那样,这种情况下正确的 ERROR_NUMBER()
是
Error 2601
我有一个名为 Form 的数据库 table,其中包含 2 列 Id 和 UserName。
我在 table 上创建了视图,其中包含列 Id 和 UserName。
在该视图中,我为列 UserName 创建了 UNIQUE CLUSTERED INDEX 因此,每当用户尝试为 UserName 插入重复值时,它都会抛出违反唯一约束的异常。
有什么办法可以达到下面的要求,
我需要附加一个递增的整数以使用户名唯一。
当用户输入 table 中已经存在的用户名时,它应该向其附加递增的整数。
插入用户名时,我们并不总是只在末尾附加一个“1”。
我需要附加一个递增的整数以使 UserName 唯一。
这与复制文件时 Windows 的行为相匹配。
如果用户插入"Tom" 3次,那么它应该创建"Tom 1", "Tom 2" 和 "Tom 3".
如果用户再次插入"Tom",那么它应该创建"Tom 4"。
再想想这个:
如果用户手动插入 "Tom" 和 "Tom 2"
用户然后插入 "Tom" - 它应该创建 "Tom 1".
用户然后再次插入 "Tom" - 它应该创建 "Tom 3" 因为 "Tom 2" 已经存在。
其类似windows文件目录。当我们在某个文件夹中 copy/pasting 文本文档时,它一遍又一遍。
我需要此功能来使用 EventSourcing 在 CQRS 中实现唯一名称,C# 应用程序,当用户复制某些实体时,例如。 FormName 它应该只是根据 Db 中存在的 FormNames 将增量整数附加到 FormName,并且可以 return 来自 db 所以,我们可以在 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
要获得您正在寻找的确切 ERROR_NUMBER(),您可以进行测试 运行,故意插入一个违反唯一约束的值,其中您的 CATCH
块是:
BEGIN CATCH
SELECT ERROR_NUMBER()
END CATCH
编辑
正如@Roshan 指出的那样,这种情况下正确的 ERROR_NUMBER()
是
Error 2601