从C#代码插入SQL数据库时重复密钥

时间:2016-05-09 15:15:45

标签: c# sql database

我正在为一个最初由另一个程序员编写的程序添加功能,现在我遇到了这个困境。当我向数据库发送此查询时,

INSERT INTO AQS_STATION_Road_Influences (STA_SerialCode,
TangentStreetNumber, TangentStreetName, RoadTypeCode,
TrafficCountValue, TrafficCountYear, DirectionToStreetCode,
TrafficCountSourceCode) Values (4, '45', '56', '3', '365', '2016',
'NE', '54'),  (141, '45', '56', '3', '365', '2016', 'NE', '54')

我得到了

  

违反PRIMARY KEY约束'PK_AQS_STATION_Road_Influences'。   无法在对象中插入重复键   'dbo.AQS_STATION_Road_Influences'。重复键值为(4,45)。

     

声明已经终止。

我在查询中检查了表没有这样的主键。当我从表中选择*时,我得到了我手动放入的3个条目。具体如下:

These are the current rows in the road influences table

此表的主键是由STA_SerialCodeTangentStreetNumber组成的复合键。令人困惑的是,如果我将插入查询直接粘贴到SQL管理器中,它运行就好了。我已经尝试一次运行插入一行,但它仍然抛出相同的错误。我也逐步完成了我的代码,以确保我认为传递的查询实际上是我想要的。为了参考,这是我认为相关的C#代码:

public int DbUpdateTable(string strQuery, DataTable dtData)
        {
            int nRows;

            try
            {
                DbProviderFactory factoryProvider = DbProviderFactories.GetFactory(_strDbProvider);
                using (DbConnection connDb = factoryProvider.CreateConnection())
                {
                    try
                    {
                        connDb.ConnectionString = _strDbConnection;
                        connDb.Open();

                        using (DbTransaction dbTrans = connDb.BeginTransaction())
                        {
                            using (DbDataAdapter adapterDb = factoryProvider.CreateDataAdapter())
                            {
                                using (DbCommand cmdDb = connDb.CreateCommand())
                                {
                                    cmdDb.Transaction = dbTrans;
                                    cmdDb.CommandText = strQuery;

                                    if (strQuery.Contains("INSERT INTO"))
                                    {
                                        adapterDb.InsertCommand = cmdDb;
                                    }
                                    else if (strQuery.Contains("DELETE FROM"))
                                    {
                                        adapterDb.DeleteCommand = cmdDb;
                                    }
                                    else
                                    {
                                        adapterDb.SelectCommand = cmdDb;
                                    }

                                    using (DbCommandBuilder bldDb = factoryProvider.CreateCommandBuilder())
                                    {
                                        try
                                        {
                                            bldDb.DataAdapter = adapterDb;
                                            nRows = adapterDb.Update(dtData);
                                            dbTrans.Commit();
                                            return (nRows);
                                        }
                                        catch (Exception dbex)//DbException dbex)
                                        {
                                            Debug.Assert(false);
                                            dbTrans.Rollback();
                                            throw new Exception(dbex.Message);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (DbException ex)
                    {
                        Debug.Assert(false);
                        throw new Exception(ex.Message);
                    }
                    finally
                    {
                        if (connDb.State != ConnectionState.Closed)
                        {
                            connDb.Close();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Debug.Assert(false);
                Trace.WriteLine("Excpt: " + e.Message, this.ToString());
                throw new CybernetException("QUERY ERROR: " + strQuery);
            }
            finally
            {
            }

        }

非常感谢任何帮助。

修改 为了便于阅读,我在这里添加了我的评论中的主键SQL代码。

ALTER TABLE [dbo].[AQS_STATION_Road_Influences] ADD CONSTRAINT
[PK_AQS_STATION_Road_Influences] PRIMARY KEY CLUSTERED (
[STA_SerialCode] ASC, [TangentStreetNumber] ASC )WITH (PAD_INDEX =
OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO

编辑2:

SQL Profiler displaying what appears to be two sent queries.

1 个答案:

答案 0 :(得分:1)

所以在找了几天之后仍然无法弄清楚为什么插件查询被发送两次,我最终只是重写了函数,现在它工作得很好。

public int SimpleDBUpdateTable(string strQuery)
    {
        int nRows;

        try
        {
            DbProviderFactory factoryProvider = DbProviderFactories.GetFactory(_strDbProvider);
            using (DbConnection connDb = factoryProvider.CreateConnection())
            {
                try
                {
                    connDb.ConnectionString = _strDbConnection;
                    connDb.Open();
                    using (DbCommand cmdDb = connDb.CreateCommand())
                    {
                        cmdDb.CommandText = strQuery;
                        nRows = cmdDb.ExecuteNonQuery();

                        return nRows;
                    }
                }
                catch (DbException ex)
                {
                    throw;
                }
                finally
                {
                    if (connDb.State != ConnectionState.Closed)
                    {
                        connDb.Close();
                    }
                }
            }
        }
        catch (Exception e)
        {
            throw;
        }
    }

我猜测重复与适配器和命令对象有关,但正如我所说,我找不到原因。