C# 捕获重复条目OLEDBEException&;过度书写

C# 捕获重复条目OLEDBEException&;过度书写,c#,oledb,C#,Oledb,在试图向Access数据库添加行时,我在处理条目时遇到此错误。问题是,我正在处理的一些条目是唯一的,有些条目可能具有重复的主键,并更新了相关列。但是,由于有些具有重复的主键,因此所有正在处理的操作都会失败 我想用新数据覆盖重复条目并添加新条目。我该怎么做 我在下面做了一些测试,试图用try/catch块解决所有失败的问题,但没有成功: using (OleDbConnection myCon = new OleDbConnection("Provider=Microsof

在试图向Access数据库添加行时,我在处理条目时遇到此错误。问题是,我正在处理的一些条目是唯一的,有些条目可能具有重复的主键,并更新了相关列。但是,由于有些具有重复的主键,因此所有正在处理的操作都会失败

我想用新数据覆盖重复条目并添加新条目。我该怎么做

我在下面做了一些测试,试图用try/catch块解决所有失败的问题,但没有成功:

            using (OleDbConnection myCon = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Lenovo\\Desktop\\Weather Cruncher\\wcMainDB.accdb"))
            {
                OleDbCommand cmd = new OleDbCommand();
                cmd.CommandText = "Insert into stations_NOAA " +
                    "([stationID],[stationName],[stationMinDate],[stationMaxDate],[stationDataCoverage]," +
                    "[stationLatitude],[stationLongitude],[stationElevation],[stationElevationUnit])" +
                    "values (?,?,?,?,?,?,?,?,?)";
                cmd.Connection = myCon;
                myCon.Open();

                // Populate Access Database
                foreach (Station loc in noaa.results)
                {
                    try
                    {
                        cmd.Parameters.AddWithValue("@stationID", loc.id); // Short Text data type
                        cmd.Parameters.AddWithValue("@stationName", loc.name); // Short Text data type
                        cmd.Parameters.AddWithValue("@stationMinDate", loc.mindate); // Short Text data type
                        cmd.Parameters.AddWithValue("@stationMaxDate", loc.maxdate); // Short Text data type
                        cmd.Parameters.AddWithValue("@stationDataCoverage", loc.datacoverage); // Number data type
                        cmd.Parameters.AddWithValue("@stationLatitude", loc.latitude); // Number data type
                        cmd.Parameters.AddWithValue("@stationLongitude", loc.longitude); // Number data type
                        cmd.Parameters.AddWithValue("@stationElevation", loc.elevation); // Number data type
                        cmd.Parameters.AddWithValue("@stationElevationUnit", loc.elevationUnit); // Short Text data type
                        cmd.ExecuteNonQuery();
                        cmd.Parameters.Clear();
                    }
                    catch(Exception ex)
                    {
                        if (ex.Message.Contains("duplicate values")) // It is a primary key violation, ignore
                        {
                            Console.WriteLine("Dupe skipped.");
                            continue;
                        }
                        else
                        {
                            MessageBox.Show(ex.ToString() + "\n\n" + ex.Message);
                        }
                    }
                }
            }

它正在处理20个查询,其中15个是唯一的。我看着它一步一步地通过,同时将主键与程序正在处理的数据进行比较。如何解决这两个问题?

< P>也许考虑这样的事情…假设Station_ID是唯一的字段

foreach (Station loc in noaa.results)
{
    cmdCount.CommandText = "SELECT count(*) from stations_NOAA WHERE StationId = @station_id";
    cmdCount.Parameters.AddWithValue("@station_id", loc.id);
    int count = (int)cmdCount.ExecuteScalar();

    if (count > 0)
    {
         // UPDATE STATEMENT
         cmd.CommandText "UPDATE stations_NOAA Set stationMinDate = @stationMinDate, Set StationMaxDate = @stationMaxDate, ...
             where StationID = @stationID;"
        cmd.Parameters.AddWithValue("@stationID", loc.id); // Short Text data type
        cmd.Parameters.AddWithValue("@stationMinDate", loc.mindate); // Short Text data type
        cmd.Parameters.AddWithValue("@stationMaxDate", loc.maxdate); // Short Text data type
        ...
        ...
        cmd.ExecuteNonQuery();
    }
    else
    {
         // INSERT STATEMENT
         commandText = ("Insert into stations_NOAA " +
                        "([stationID],[stationName],[stationMinDate],[stationMaxDate],[stationDataCoverage]," +
                        "[stationLatitude],[stationLongitude],[stationElevation],[stationElevationUnit])" +
                        "values (?,?,?,?,?,?,?,?,?)";
         cmd.Parameters.AddWithValue("@stationID", loc.id); // Short Text data type
        cmd.Parameters.AddWithValue("@stationMinDate", loc.mindate); // Short Text data type
        cmd.Parameters.AddWithValue("@stationMaxDate", loc.maxdate); // Short Text data type
        ...
        ...
        cmd.ExecuteNonQuery();
    }
    cmd.Parameters.Clear();
}
如果更新和插入中的所有参数都相同,则此模式:

foreach (Station loc in noaa.results)
{
    cmd.CommandText = "SELECT count(*) from stations_NOAA WHERE StationId = @station_id", myConnection);
    cmdCount.Parameters.AddWithValue("@station_id", loc.id);
    int count = (int)cmdCount.ExecuteScalar();

    if (count > 0)
        cmd.CommandText "UPDATE stations_NOAA " _
            "Set stationMinDate = @stationMinDate, " _
            "Set StationMaxDate = @ StationMaxDate, " _
               ...
            "where StationID = @stationID;"

    else
        commandText = "Insert into stations_NOAA " +
                        "([stationID],[stationName],[stationMinDate],[stationMaxDate],[stationDataCoverage]," +
                        "[stationLatitude],[stationLongitude],[stationElevation],[stationElevationUnit])" +
                        "values (@stationID,@stationMinDate, @ ...)";

    cmd.Parameters.AddWithValue("@stationID", loc.id); // Short Text data type
    cmd.Parameters.AddWithValue("@stationMinDate", loc.mindate); // Short Text data type
    cmd.Parameters.AddWithValue("@stationMaxDate", loc.maxdate); // Short Text data type
    ...
    ...

    cmd.ExecuteNonQuery();      

    cmd.Parameters.Clear();
}

<>但是如果插入和更新都具有相同的字段,而且它更干净/更容易阅读,那么只能起作用。假设Station_ID是唯一的字段

foreach (Station loc in noaa.results)
{
    cmdCount.CommandText = "SELECT count(*) from stations_NOAA WHERE StationId = @station_id";
    cmdCount.Parameters.AddWithValue("@station_id", loc.id);
    int count = (int)cmdCount.ExecuteScalar();

    if (count > 0)
    {
         // UPDATE STATEMENT
         cmd.CommandText "UPDATE stations_NOAA Set stationMinDate = @stationMinDate, Set StationMaxDate = @stationMaxDate, ...
             where StationID = @stationID;"
        cmd.Parameters.AddWithValue("@stationID", loc.id); // Short Text data type
        cmd.Parameters.AddWithValue("@stationMinDate", loc.mindate); // Short Text data type
        cmd.Parameters.AddWithValue("@stationMaxDate", loc.maxdate); // Short Text data type
        ...
        ...
        cmd.ExecuteNonQuery();
    }
    else
    {
         // INSERT STATEMENT
         commandText = ("Insert into stations_NOAA " +
                        "([stationID],[stationName],[stationMinDate],[stationMaxDate],[stationDataCoverage]," +
                        "[stationLatitude],[stationLongitude],[stationElevation],[stationElevationUnit])" +
                        "values (?,?,?,?,?,?,?,?,?)";
         cmd.Parameters.AddWithValue("@stationID", loc.id); // Short Text data type
        cmd.Parameters.AddWithValue("@stationMinDate", loc.mindate); // Short Text data type
        cmd.Parameters.AddWithValue("@stationMaxDate", loc.maxdate); // Short Text data type
        ...
        ...
        cmd.ExecuteNonQuery();
    }
    cmd.Parameters.Clear();
}
如果更新和插入中的所有参数都相同,则此模式:

foreach (Station loc in noaa.results)
{
    cmd.CommandText = "SELECT count(*) from stations_NOAA WHERE StationId = @station_id", myConnection);
    cmdCount.Parameters.AddWithValue("@station_id", loc.id);
    int count = (int)cmdCount.ExecuteScalar();

    if (count > 0)
        cmd.CommandText "UPDATE stations_NOAA " _
            "Set stationMinDate = @stationMinDate, " _
            "Set StationMaxDate = @ StationMaxDate, " _
               ...
            "where StationID = @stationID;"

    else
        commandText = "Insert into stations_NOAA " +
                        "([stationID],[stationName],[stationMinDate],[stationMaxDate],[stationDataCoverage]," +
                        "[stationLatitude],[stationLongitude],[stationElevation],[stationElevationUnit])" +
                        "values (@stationID,@stationMinDate, @ ...)";

    cmd.Parameters.AddWithValue("@stationID", loc.id); // Short Text data type
    cmd.Parameters.AddWithValue("@stationMinDate", loc.mindate); // Short Text data type
    cmd.Parameters.AddWithValue("@stationMaxDate", loc.maxdate); // Short Text data type
    ...
    ...

    cmd.ExecuteNonQuery();      

    cmd.Parameters.Clear();
}

但是,只有当插入和更新都有相同的字段并且更清晰/更容易阅读时,这才有效。

您需要对已经存在的记录执行“更新”而不是“插入”。在catch块中执行此操作的正确方法是否与我设置它的方法类似,或者我需要首先检查是否存在重复项,然后相应地采取行动?我将一次处理多达10K个查询,并关注效率不,如果效率是一个问题,肯定不是“正确的方法”。你能提供更多信息吗?“计数”然后“插入”或“更新”取决于结果,在这个实例中,使用catch块“hack”可以执行20K个操作,而不是10K个操作。您只需要一个
。选择类似
things的
语句。选择(x=>x.id)。ToHashSet()
。只需再编写几行代码,但可能会节省大量时间。1分贝呼叫,获取10000的相同信息。我不确定access在in中处理10k项的效果如何,但我在其他DBMS中很少使用它。您需要对已经存在的记录执行“更新”而不是“插入”。在catch块中执行此操作的正确方法与我设置它的方法类似,还是需要首先检查是否存在重复项,然后相应地采取行动?我将一次处理多达10K个查询,并关注效率不,如果效率是一个问题,肯定不是“正确的方法”。你能提供更多信息吗?“计数”然后“插入”或“更新”取决于结果,在这个实例中,使用catch块“hack”可以执行20K个操作,而不是10K个操作。您只需要一个
。选择类似
things的
语句。选择(x=>x.id)。ToHashSet()
。只需再编写几行代码,但可能会节省大量时间。1分贝呼叫,获取10000的相同信息。我不确定access在in中处理10k项的效果如何,但我在其他DBMS中很少使用它。感谢您在上面的评论中提供有关避免使用我的创造性解决方案的帮助和解释。感谢您在上面的评论中提供有关避免使用我的创造性解决方案的帮助和解释。