You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL CE中防止重复插入?附SqlCeCommand代码咨询

关于SQL CE实现防重复插入的问题解答

嘿,我来帮你梳理下这个问题~首先你的代码里有两个关键问题:

  1. 拼写错误:ON DUBLICATE应该是ON DUPLICATE
  2. 核心问题:SQL Compact Edition(SQL CE)并不支持MySQL的ON DUPLICATE KEY UPDATE语法,所以这段代码执行时肯定会抛出语法错误,没法实现你想要的防重复插入+更新的需求。

下面给你几种SQL CE支持的正确实现方式,根据你的场景选就行:

方法1:使用MERGE语句(推荐,原子操作)

SQL CE 3.5及以上版本支持MERGE语法,这是原子性的操作,能避免并发情况下的冲突问题。假设你的fpl_table中FLIGHT_ID是主键或者唯一键(用来判断重复的依据),可以这么写:

// 构建MERGE语句,根据FLIGHT_ID判断是否重复
string sql = @"MERGE INTO fpl_table AS target
USING (SELECT @FLIGHT_ID AS FLIGHT_ID, @BPN_TIME AS BPN_TIME, @BPX_TIME AS BPX_TIME, @DAY_NB AS DAY_NB) AS source
ON target.FLIGHT_ID = source.FLIGHT_ID
WHEN MATCHED THEN 
    UPDATE SET BPN_TIME = source.BPN_TIME, BPX_TIME = source.BPX_TIME, DAY_NB = source.DAY_NB
WHEN NOT MATCHED THEN 
    INSERT (FLIGHT_ID, BPN_TIME, BPX_TIME, DAY_NB) VALUES (source.FLIGHT_ID, source.BPN_TIME, source.BPX_TIME, source.DAY_NB);";

SqlCeCommand command = new SqlCeCommand(sql, connection);
command.Parameters.AddWithValue("@FLIGHT_ID", format);
command.Parameters.AddWithValue("@BPN_TIME", format1);
command.Parameters.AddWithValue("@BPX_TIME", format2);
command.Parameters.AddWithValue("@DAY_NB", format3);

// 执行命令
command.ExecuteNonQuery();

方法2:先判断存在性再执行更新/插入(适合老版本SQL CE)

如果你的SQL CE版本低于3.5,不支持MERGE,可以先查询是否存在对应记录,再决定执行UPDATE还是INSERT。注意这种方法在高并发场景下可能出现竞态条件,最好配合事务使用:

// 先检查是否存在记录
string checkSql = "SELECT COUNT(*) FROM fpl_table WHERE FLIGHT_ID = @FLIGHT_ID";
SqlCeCommand checkCmd = new SqlCeCommand(checkSql, connection);
checkCmd.Parameters.AddWithValue("@FLIGHT_ID", format);
int count = (int)checkCmd.ExecuteScalar();

SqlCeCommand command;
if (count > 0)
{
    // 存在则更新
    string updateSql = @"UPDATE fpl_table 
                         SET BPN_TIME = @BPN_TIME, BPX_TIME = @BPX_TIME, DAY_NB = @DAY_NB
                         WHERE FLIGHT_ID = @FLIGHT_ID";
    command = new SqlCeCommand(updateSql, connection);
}
else
{
    // 不存在则插入
    string insertSql = @"INSERT INTO fpl_table (FLIGHT_ID, BPN_TIME, BPX_TIME, DAY_NB) 
                         VALUES (@FLIGHT_ID, @BPN_TIME, @BPX_TIME, @DAY_NB)";
    command = new SqlCeCommand(insertSql, connection);
}

// 添加参数
command.Parameters.AddWithValue("@FLIGHT_ID", format);
command.Parameters.AddWithValue("@BPN_TIME", format1);
command.Parameters.AddWithValue("@BPX_TIME", format2);
command.Parameters.AddWithValue("@DAY_NB", format3);

// 执行命令
command.ExecuteNonQuery();

方法3:TRY/CATCH捕获主键冲突(简单场景可用)

还可以尝试直接执行INSERT,如果因为主键/唯一键冲突报错(错误码2627),就执行UPDATE:

string insertSql = @"INSERT INTO fpl_table (FLIGHT_ID, BPN_TIME, BPX_TIME, DAY_NB) 
                     VALUES (@FLIGHT_ID, @BPN_TIME, @BPX_TIME, @DAY_NB)";
string updateSql = @"UPDATE fpl_table 
                     SET BPN_TIME = @BPN_TIME, BPX_TIME = @BPX_TIME, DAY_NB = @DAY_NB
                     WHERE FLIGHT_ID = @FLIGHT_ID";

SqlCeCommand command = new SqlCeCommand(insertSql, connection);
command.Parameters.AddWithValue("@FLIGHT_ID", format);
command.Parameters.AddWithValue("@BPN_TIME", format1);
command.Parameters.AddWithValue("@BPX_TIME", format2);
command.Parameters.AddWithValue("@DAY_NB", format3);

try
{
    command.ExecuteNonQuery();
}
catch (SqlCeException ex)
{
    // 捕获主键/唯一键冲突错误(错误码2627)
    if (ex.Errors.Cast<SqlCeError>().Any(e => e.NativeError == 2627))
    {
        command.CommandText = updateSql;
        command.ExecuteNonQuery();
    }
    else
    {
        // 其他错误重新抛出
        throw;
    }
}

内容的提问来源于stack exchange,提问作者Fazka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:14:56