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

时间:2017-09-21 16:47:41

标签: c# sql .net sqlite sql-update

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

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

我的问题是这样的:有时快速的过程将会完成"记录(意味着它不再需要更新)在缓慢的过程之前,以及在夜间批处理过程中的当天晚些时候,#34;完成"记录将被过时的"待定"取代在慢速流程的批量数据中找到的记录。

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

If(record_is_not_complete or does_not_exist) 
{ INSERT or REPLACE; }
Else 
{ do_nothing and move_to_the_next; }

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

INSERT OR REPLACE INTO UserProgress (id, status, level) 
  VALUES (1, 'COMPLETE', 5);

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

如果发生以下情况:

INSERT OR REPLACE INTO UserProgress (id, status, level) 
  VALUES (1, 'PENDING', 4);

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

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

我可以尝试添加CASE语句,我被告知它等同于IF-THEN-ELSE语句。 As done in this example.

我可以尝试在SELECT中使用COALESCEVALUES语句。 As done in this example.

我甚至可以尝试使用SELECT WHERE语句。 As done in this example.

我可以尝试使用LEFT JOIN语句。 As done in this example.

哪个适合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();
                }
            }
        }

2 个答案:

答案 0 :(得分:16)

<强> SQL

INSERT OR REPLACE INTO UserProgress (id, status, level) SELECT id值 , ' 状态值 ', 级别值 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)。

答案 1 :(得分:2)

IF语句有三种形式:IF-THEN,IF-THEN-ELSE和IF-THEN-ELSIF。

在SQLite中使用If语句的语法是:

IF expr THEN statement-list
[ELSIF expr THEN statement-list ]*
[ELSE statement-list]
END IF

已关联:https://www.sqliteconcepts.org/pl_if.html