2

我有一个包含一些列的表,并且我在其中 3 个列上设置了唯一键,以确保表中没有重复项。现在我想知道是否使用 try / catch 来吞下重复项上的异常并继续更新插入下一行foreach是一个好方法吗?

            try {
                sqlWrite.ExecuteNonQuery();
            } catch (SqlException sqlException) {
                if (!sqlException.ToString().Contains("Violation of UNIQUE KEY constraint")) {
                    MessageBox.Show("Error - " + Environment.NewLine + sqlException.ToString(), "Error SQL");
                }
            } catch (Exception exception) {
                MessageBox.Show("Error - " + Environment.NewLine + exception.ToString(), "Error SQL");
            }

或者我应该在插入查询中执行 SELECT 以检查行是否存在以及是否跳过插入?我已经读到使用异常作为数据验证的一部分是不好的,但有些东西应该像那样使用(例如如何在 C# 中检查文件锁定?应该与 try/catch 一起使用)。

4

2 回答 2

1

如果您有其他方法可以做到这一点,则永远不应该抛出和捕获异常。而你现在拥有它。用它!

您可以创建单个 sql 脚本或存储过程来检查和插入IF NOT EXISTS(SELECT ...). 进行两个查询比较慢。

于 2012-04-10T15:06:05.983 回答
0

我一般会说主键关系应该是数据验证的绝对最后和后备位置。如果你的程序已经走到了这一步,并且试图插入一个唯一键失败的行,那么就出了很大的问题。

在最简单的情况下,它并不算太糟糕。对于插入单行,没有任何其他依赖项,您可以提出一个参数,即尝试插入记录并引发捕获的错误可能比执行选择以查看 ID 是否已存在更有效。

现在,考虑一个事务,您可能一次插入/更新 10 行甚至数百行。每一行都有一个唯一的键,其中任何一行都可能引发错误。然后,当捕获到错误时,数据库必须回滚整个事务。当然 C# 具有事务模式,但是您必须回滚数据库并回滚在插入记录时可能已更新的任何对象。它变得非常复杂非常快。

于 2012-04-10T15:09:00.707 回答