如何在SQLite中有条件地插入或替换行?

sap*_*ket 13 .net c# sql sqlite sql-update

我想插入或替换_on_condition.如果不满足条件,请勿插入或更换.这可能吗?

对于我的项目,我目前有两个数据收集过程.一个是快速但不能抓住一切.另一个是缓慢但捕获一切.通过快速流程,我几乎可以实时获取数据.由于速度慢,我在一天结束时使用批处理获取数据.

我的问题是:有时快速流程将"完成"一条记录(意味着它不再需要更新)在缓慢的流程之前,以及在夜间批处理过程中的当天晚些时候,"完整"记录将被替换为在慢速流程的批量数据中找到过时的"待定"记录.

我想要的是一个类似于这个伪代码的条件检查:

If(record_is_not_complete or does_not_exist) 
{ INSERT or REPLACE; }
Else 
{ do_nothing and move_to_the_next; }
Run Code Online (Sandbox Code Playgroud)

如果我从标准INSERT OR REPLACE示例开始:

INSERT OR REPLACE INTO UserProgress (id, status, level) 
  VALUES (1, 'COMPLETE', 5);
Run Code Online (Sandbox Code Playgroud)

哪个应该在UserProgress表中输入一行,条目为[1,COMPLETE,5].

如果发生以下情况:

INSERT OR REPLACE INTO UserProgress (id, status, level) 
  VALUES (1, 'PENDING', 4);
Run Code Online (Sandbox Code Playgroud)

我希望它跳过这个,因为已经有一个完整的记录.

我确定这是一个重复的问题.但它真的吗?这个问题有很多答案,我不确定哪种方法最好.看看我发现的所有这些例子:

我可以尝试添加一个CASE声明,我被告知它等同于一个IF-THEN-ELSE声明.正如本例中所做的那样.

我可以尝试使用SELECTCOALESCE声明VALUES.正如本例中所做的那样.

我甚至可以尝试使用一个SELECT WHERE声明.正如本例中所做的那样.

我可以尝试使用一个LEFT JOIN声明.正如本例中所做的那样.

这对SQLite来说很棒.似乎有多种方法可以为同一只猫皮肤涂抹.我是一个新手我现在很困惑.目前尚不清楚我应该使用哪种方法.

我正在寻找一个可以在一个sql语句中完成的解决方案.

*更新*

我找到了两个交易解决方案.我还在寻找单一的交易解决方案.

这有效,但使用两个事务:

 public void Create(IEnumerable<UserProgress> items)
        {
            var sbFields = new StringBuilder();
            sbFields.Append("ID,");
            sbFields.Append("STATUS,");
            sbFields.Append("LEVEL,");

            int numAppended = 3;

            var sbParams = new StringBuilder();
            for (int i = 1; i <= numAppended; i++)
            {
                sbParams.Append("@param");
                sbParams.Append(i);

                if (i < numAppended)
                {
                    sbParams.Append(", ");
                }
            }

            // attempting this solution: https://stackoverflow.com/questions/2251699/sqlite-insert-or-replace-into-vs-update-where

            // first insert the new stuff.
            using (var command = new SQLiteCommand(Db))
            {               

                command.CommandText = "INSERT OR IGNORE INTO USERPROGRESS (" + sbFields + ") VALUES(" + sbParams + ")";

                command.CommandType = CommandType.Text;

                using (var transaction = Db.BeginTransaction())
                {
                    foreach (var user in items)
                    {
                        command.Parameters.Add(new SQLiteParameter("@param1", user.Id));
                        command.Parameters.Add(new SQLiteParameter("@param2", user.Status));
                        command.Parameters.Add(new SQLiteParameter("@param3", user.Level));

                        command.ExecuteNonQuery();
                    }

                    transaction.Commit();
                }
            }

            using (var command = new SQLiteCommand(Db))
            {
                string parameterized = "";

                for (int i = 1; i <= 3; i++)
                {
                    parameterized += _columnNames[i - 1] + "=" + "@param" + i;

                    if (i != 3)
                        parameterized += ",";
                }

                command.CommandText = "UPDATE USERPROGRESS SET " + parameterized + " WHERE ID=@param1 AND STATUS !='COMPLETE'";

                command.CommandType = CommandType.Text;

                using (var transaction = Db.BeginTransaction())
                {
                    foreach (var user in items)
                    {
                        command.Parameters.Add(new SQLiteParameter("@param1", user.Id));
                        command.Parameters.Add(new SQLiteParameter("@param2", user.Status));
                        command.Parameters.Add(new SQLiteParameter("@param3", user.Level));

                        command.ExecuteNonQuery();
                    }

                    transaction.Commit();
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

Ste*_*ers 17

SQL

INSERT OR REPLACE INTO UserProgress (id, status, level) SELECTid值, '状态值',级别值 WHERE NOT EXISTS (SELECT * FROM UserProgress WHERE id =id值AND status = 'COMPLETE');

(根据需要插入id值,状态值级别值)

演示

http://www.sqlfiddle.com/#!5/a9b82d/1

说明

EXISTS部分用于查明表中是否存在具有相同id状态值的现有行'COMPLETE'.如果匹配此条件,则不执行任何操作(由于WHERE NOT).否则,具有指定的行id如果不存在则为INSERTed,如果存在,则为具有指定值的UPDATEd(由于INSERT OR REPLACE).