【问题标题】:How to let the user to enter primary keys manually如何让用户手动输入主键
【发布时间】:2012-01-31 14:39:18
【问题描述】:

我的 ASP.NET 网站要求我让用户手动输入特定表的主键,如果用户输入了数据库中已经存在的主键,系统应该通知用户作为“主要已经存在”或类似的东西。

我正在考虑让用户输入主键,当他输入一个已经存在的键时,系统将抛出主键约束违反异常。因此,我将捕获该异常,并在 catch 块中显示一条错误消息,以通知用户主键重复。但是,我不确定这是正确的方法还是有任何标准的方法可以做到这一点?

【问题讨论】:

  • 为什么不先检查密钥是否存在,而不是尝试捕获错误?这不像通过主键查找单行会减慢您的应用程序:)
  • 如果有一个搜索功能,用户只输入主键,然后您返回一个查询结果来检查该主键是否已经存在?

标签: c# asp.net sql-server database


【解决方案1】:

是的,这是一种有效的方法。不过,有几件事应该提到:

  • 使用surrogate key(计数器、GUID、...)代替用户输入的值(自然键)作为主键有很多优点,有关详细信息,请参阅链接文章。如果您已经考虑过这一点并决定使用自然键,那很好,我只是认为应该提及它。如果使用代理键,可以通过唯一索引保证用户自定义值的唯一性。

  • 将异常作为正常控制流的一部分引发通常是不受欢迎的:对现有键执行 SELECT 然后 INSERT 比等待异常发生更优雅。 (使用事务和适当的事务隔离级别来确保其他客户端不会在您的 SELECT 和 INSERT 之间插入任何行)。

【讨论】:

    【解决方案2】:

    在尝试将新记录插入数据库之前,只需对目标表进行查询以查看主键是否已存在。如果是,则向用户返回一条消息。

    【讨论】:

      【解决方案3】:

      这太难看了。对“正常”逻辑流使用异常并不是一个好主意——它使代码更难阅读和维护,而且往往更慢(尽管您可能不会注意到性能影响)。

      我将其拆分为“验证”方法,该方法应验证用户输入的数据 - 它是正确的数据类型吗?它是否满足最小长度要求?它是独一无二的吗?

      如果“验证”方法返回违规,则向用户显示;给他们机会修复它。

      如果“验证”方法没有返回违规,请尝试插入记录,并捕获“重复键”异常(其他人可能在您验证和输入记录之间的时间内输入了该记录)。

      【讨论】:

        【解决方案4】:

        我不打算讨论你是否应该这样做(顺便说一句,我认为你不应该这样做:p)但这是代码:

        SET IDENTITY_INSERT TABLE ON
        

        请记住,每个数据库只能有一个表设置为 ON

        【讨论】:

        • 仅当主键字段是 IDENTITY 字段时才需要。
        • 是的,我以为是身份
        【解决方案5】:

        MS Sql Server 中的主键是唯一索引。如果您违反索引约束,数据库将引发错误并回滚事务。

        如果您能够正确维护索引名称,您将能够将您提出的解决方案用于其他情况。

        恕我直言,这种方法很好。通常的替代方法是询问数据库中是否存在值。如果找到,最终也会出现异常。如果您决定让数据库引发异常,请不要忘记在代码文档中提及。因为在没有此类信息的情况下使用它可能会在将来导致一些问题。

        【讨论】:

          【解决方案6】:

          为什么要让用户编写主键并猜测要输入什么以及它是否已经被占用?我的意思是,我知道 int 是一个范围广泛的数字,但用户可能会尝试 3-4 位数字;最终,他们会开始重复。所以为什么??你不必要地复杂化了。

          让数据库生成 id。如有必要,向用户报告。再简单不过了。

          【讨论】:

          • 我也很想这样做,但是用户强迫我这样做。我别无选择:(
          • 好吧,那么你的雇主在智力量表上缺少几分。在您想到的任何环境中,都无法证明该特定要求是合理的。如果您在填写该表格时已经指出给用户带来的明显不便,那么您已经完成了您的工作。让聪明的雇主稍后处理不便的投诉。我敢打赌,钱会花在将来谈论可用性投诉上,而且他肯定会在某个时候从该表单中删除该 PK 字段。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-11-25
          • 2020-05-26
          • 1970-01-01
          • 2018-08-22
          • 2012-08-10
          • 1970-01-01
          • 2021-10-31
          相关资源
          最近更新 更多