【问题标题】:Is it possible to easily detect or predict a Primary Key violation in SQL?是否可以轻松检测或预测 SQL 中的主键违规?
【发布时间】:2009-06-11 10:31:25
【问题描述】:

我的问题是我想运行一个查询来检查我正在使用的数据是否与数据库中已有的数据重复,例如我有一个产品代码并希望停止多次列出相同的项目,并且此产品代码是主键。
我可以避免这样做吗:

SELECT ProductCode FROM tblProducts WHERE ProductCode = '12345'

然后检查任何返回的记录,或者是否有更优雅的解决方案,我不介意使用这种方法,但它看起来很笨重。这只是对我的代码的一些额外验证,因为产品的插入应该只发生一次 - 但我希望对此进行错误检查,因为由于刷新或后退按钮的使用(基于 Web 的系统)而输入了重复项。

想知道这是 P = NP 类型的问题还是我想多了?
如果有帮助,我的数据库是 MS SQL Server 2000。

【问题讨论】:

  • 这不是 P = NP 问题,你肯定想多了。你真的需要修复刷新和后退按钮的使用,因为这从来都不好。
  • 是的,感谢您的反馈 - 处理后退按钮和刷新是所有基于 Web 的系统都必须处理的问题 - 这似乎是唯一出现的问题,与重新加载。

标签: sql sql-server database primary-key


【解决方案1】:

我建议让 SQL 插入失败,让 SQL Server 通过主键冲突错误并处理它。 SQL Server 维护一个索引,他们已经这样做了多年。我很确定他们的实现会比大多数开发人员好很多倍。如果您尝试为此进行编程,则需要读取所有键并将它们保存在某个索引中。 SQL Server 已经在这样做了。所以你有双重检查和双倍所需的空间量。

如果与您的数据库的连接由于某种或其他原因非常慢,我会考虑这样做。

否则让 SQL Server 做它擅长的事情,剩下的交给你 :)

【讨论】:

  • 在“SQL的艺术”中推荐这种方法。 amazon.com/Art-SQL-Stephane-Faroult/dp/0596008945
  • 这似乎是最好的选择,因为发生错误我只是希望它停在那里,并且此选项允许显示此错误消息以指示添加了重复项。
  • 这是一个可以接受的解决方案,除了发帖人询问如何处理后退按钮。
  • 假设您的意思是“让 SQL Server 抛出主键违规错误”
  • SQL 无论如何都会进行查找,因此您不应该提前自己做这件事而加倍努力。让错误发生。
【解决方案2】:

只允许 SQL 在插入之前先进行测试

IF NOT EXISTS (SELECT * FROM tblProducts WHERE tblProducts = '12345')
    INSERT tblProducts (tblProducts, columnlist, ...)
    VALUES ('12345', valuelist, ...)

这更好地包装在存储过程中,因此它可以自包含在数据库中(但每个人对此都有自己的看法)。

【讨论】:

  • 这将是我的选择,但重复的情况是我想要处理的例外情况,因为产品代码是条形码编号,并且它们的冲突会更早地检测到,但这是我想要进行的额外检查。
【解决方案3】:

您可以在进行提取时按列分组,如果它在那里重复,您只会得到一行。如果您要返回多个列,只需按您要返回的所有列进行分组。

【讨论】:

    【解决方案4】:

    我想这取决于这种情况发生的频率。

    如果这种情况很少发生,我会捕捉违规的可能性,如果发生,相应地通知用户。

    如果它可以相当频繁地发生,我可能会首先检查我的新项目是否正常,并且只有在实际情况下才能插入。另一方面,如果这似乎相当频繁地发生,那么您的应用程序逻辑一定有问题,我会说 - 您确实应该有一种可靠的方法来创建和分配唯一的主键(因此永远不会导致插入冲突),例如通过使用 INT IDENTITY 列或其他方式。

    马克

    【讨论】:

    • 这个问题比较少见,只在少数情况下出现。我可能会调整程序逻辑,但这会发生在普通应用程序的多个页面上,现有代码可以正常工作 - 基于 Web 的似乎引入了正常应用程序永远不会遇到的后退按钮和刷新等问题 - 以及处理异常的更好方法!
    【解决方案5】:

    也许问题出在您的网络应用程序的设计上?您是否确保仅通过 http POST 对数据库中的数据进行变异。然后确保这些页面响应的过期时间为零或现在(我不记得它是基于日期还是基于毫秒)。这样,回击的用户将看到“您要重新发布表单数据”消息,或从浏览器中获得“页面已过期”链接。

    接下来,任何接受用户输入的页面都需要容错。您的用户似乎输入了您的主键。但是,即使输入唯一键而不是计算数据也是合理的。

    您处理这种情况的一般策略是什么? (不是p = np)这个问题面临着许多数据库类型的应用程序。似乎其他海报已经为这个问题提供了一些解决方案。

    祝你好运

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多