我想插入或替换_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
中使用COALESCE
或VALUES
语句。 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();
}
}
}
答案 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