我的ASP.NET网站要求我让用户手动输入特定表的主键,如果用户输入了数据库中已存在的主键,系统应该通知用户为“主要已存在”或类似的东西。
我想让用户输入主键,当他输入已经存在的键时,系统将抛出主键约束违例的异常。因此,我将捕获该异常,并且在catch块中,我将显示一条错误消息,通知用户主键的重复。但是,我不确定这是一种正确的方法,还是有任何标准方法可以做到这一点?
答案 0 :(得分:5)
是的,这是一种有效的方法。不过应该提到一些事情:
使用surrogate key(计数器,GUID,...)作为主键而不是用户输入的值(自然键)有很多优点,请参阅链接的文章细节。如果您已经考虑过并决定使用自然键,那很好,我只是认为应该提到它。如果您使用代理键,则可以通过唯一索引确保用户定义值的唯一性。
作为正常控制流程的一部分抛出异常通常不赞成:对现有密钥执行SELECT,然后INSERT将比等待异常发生更优雅。 (使用事务和适当的事务隔离级别,以确保SELECT和INSERT之间的其他客户端不能插入任何行。)
答案 1 :(得分:1)
在尝试在数据库中插入新记录之前,只需对目标表执行查询,以查看主键是否已存在。如果是,请向用户返回一条消息。
答案 2 :(得分:1)
那太难看了。对“正常”逻辑流使用异常并不是一个好主意 - 它使代码更难以读取和维护,并且往往更慢(尽管您可能不会注意到性能影响)。
我将其拆分为“验证”方法,该方法应验证用户输入的数据 - 它是否是正确的数据类型?它是否符合最低长度要求?它有独特之处吗?
如果“validate”方法返回违规,请将其显示给用户;给他们修理它的机会。
如果“验证”方法未返回违规,请尝试插入记录,并捕获“重复密钥”异常(其他人可能在验证和输入记录之间的时间内输入了该记录)。
答案 3 :(得分:1)
我不会讨论你是否应该这样做(我不认为你应该这样做:p)但这是代码:
SET IDENTITY_INSERT TABLE ON
请记住,每个数据库只能将一个表设置为ON
答案 4 :(得分:1)
MS Sql Server中的主键是唯一索引。如果违反索引约束,数据库将引发错误并回滚事务。
如果您能够正确维护索引名称,您将能够使用您提出的其他案例解决方案。
恕我直言,这种方法很好。通常的另一种方法是询问数据库中是否存在值。如果被发现,最终也会以异常结束。如果您决定让db引发异常,请不要忘记在代码文档中提及。因为没有这些信息的使用可能会导致将来出现一些问题。答案 5 :(得分:1)
为什么要打扰用户制作主键并猜测输入内容以及是否已经使用?我的意思是,我知道int是一个广泛的数字,但用户可能会尝试3-4位数字;最终,他们将开始打击重复。所以为什么??你不必要地复杂化了。
让db生成id。如有必要,请将其报告给用户。不能简单。