在插入之前检查现有记录

Posted

技术标签:

【中文标题】在插入之前检查现有记录【英文标题】:check existing record before inserting 【发布时间】:2011-02-16 14:46:03 【问题描述】:

我想使用 C# 和 SQL Server 2000 作为数据库插入多条记录 (~1000),但在插入之前如何检查我正在插入的记录是否已经存在,如果存在,则应插入下一条记录。记录来自结构化的 excel 文件,然后我将它们加载到通用集合中并遍历每个项目并像这样执行插入

// Insert records into database
private void insertRecords() 

  try 
    // iterate through all records 
    // and perform insert on each iteration
    for (int i = 0; i < names.Count; i++) 
      sCommand.Parameters.AddWithValue("@name", Names[i]);
      sCommand.Parameters.AddWithValue("@person", ContactPeople[i]);
      sCommand.Parameters.AddWithValue("@number", Phones[i]);
      sCommand.Parameters.AddWithValue("@address", Addresses[i]); 

      // Open the connection
      sConnection.Open();
      sCommand.ExecuteNonQuery();
      sConnection.Close();

    
   catch (SqlException ex) 
    throw ex;
  

此代码使用存储过程插入记录,但我可以在插入前检查记录吗?

【问题讨论】:

【参考方案1】:

在您的存储过程中,您可以进行这样的检查(猜测表和列名,因为您没有指定):

IF EXISTS(SELECT * FROM dbo.YourTable WHERE Name = @Name)
     RETURN

-- here, after the check, do the INSERT

您可能还想在 Name 列上创建一个 UNIQUE INDEX,以确保不存在具有相同值的两行:

CREATE UNIQUE NONCLUSTERED INDEX UIX_Name
   ON dbo.YourTable(Name)

【讨论】:

所以我研究了批量插入许多记录,我发现使用 SQLDataAdapter 来执行多个插入,而不必每次都打开和关闭连接。该代码没有报告它已成功运行,但新记录不是数据库,我不知道是什么原因造成的。这是我的代码—— code string sql = "SELECT * FROM DEBTOR"; // Create data adapter SqlDataAdapter da = new SqlDataAdapter(sql, ConnectionString); // Create and fill dataset DataSet ds = new DataSet(); da.Fill(ds, "debtor"); // Get data table reference DataTable dt = ds.Tables["debtor"]; sCommand.UpdatedRowSource = UpdateRowSource.None; SqlDataAdapter adpt = new SqlDataAdapter(); -- 继续 for (int i = 0; i @user619846:请不要将代码和内容发布到 cmets - 它非常难以阅读!如果您有代码,请通过 EDITING 更新您的原始问题并提供该代码!【参考方案2】:

最简单的方法可能是在循环中添加一个内部 try 块。如果它们不是重复记录错误,则捕获任何数据库错误并重新抛出它们。如果是重复记录错误,那么什么都不做(吃掉异常)。

【讨论】:

【参考方案3】:

在存储过程中,对于要添加到数据库的行,首先检查该行是否存在于表中。如果它存在,UPDATE 它,否则INSERT 它。 SQL 2008 也有MERGE 命令,它基本上将更新和插入结合在一起。

就性能而言,RBAR (row-by-agonizing-row) 效率很低。如果速度是一个问题,您需要查看各种“一次插入大量行”过程:BULK INSERT、bcp 实用程序和 SSIS 包。你仍然有非此即彼的问题,但至少它会表现得更好。


编辑:

将数据批量插入空表很容易。在非空表中批量插入数据很容易。将数据批量插入到已经存在某些数据(可能由主键定义)的表中是很棘手的。唉,具体步骤很快就会变得详细,并且非常依赖于您的系统、代码、数据结构等。

要遵循的一般步骤是: - 创建一个临时表 - 将数据加载到临时表中 - 将临时表的内容与目标表的内容进行比较 - 它们匹配的地方(旧数据),更新 - 不匹配的地方(新数据),插入

我在 SO 上快速搜索了涵盖此内容的其他帖子,并偶然发现了一些我从未想过的事情。试试this;它不仅可以工作,而且很优雅。

【讨论】:

我同意你的观点,但我对 SQL 不是那么好,如果你能给我一个例子来说明我将如何检查行的存在吗?性能也绝对是一个问题,所以我会研究 BULK INSERT【参考方案4】:

您的表有主键吗?如果是这样,您应该能够检查要插入的键值是否已经在表中。

【讨论】:

我的表确实有一个主键(我使用 IDENTITY),但我想防止插入相同的名称,也就是说,如果 Peter jones 存在则名为 ContactName 的列,然后是 Excel 文件中的 Peter Jones不应再次插入

以上是关于在插入之前检查现有记录的主要内容,如果未能解决你的问题,请参考以下文章

实体框架:在插入新记录之前检查记录是不是存在

NSManagedObject 不插入它:相关的很多

如何在现有表的中间插入新的数据库记录?

laravel 在插入之前检查记录是不是存在,这是一种有效的方法

在插入新记录之前触发检查部门的平均工资

如何在将大量数据插入数据库之前检查记录是不是存在?