Я хотел бы вставить или заменить_con_condition. Если условие не выполняется, не вставляйте и не заменяйте. Это возможно?
В моем проекте у меня в настоящее время есть два процесса сбора данных. Один быстро, но не все. Другой медленный, но ловит все. С быстрым процессом я получаю данные почти в режиме реального времени. С медленным я получаю данные, используя пакетный процесс в конце дня.
Моя проблема заключается в следующем: иногда быстрый процесс будет "завершать" запись (это значит, что ее больше не нужно обновлять) ПЕРЕД медленным процессом, а позже в течение дня в ночном режиме партии, "полная" запись будет замените на устаревшую "ожидающую" запись, обнаруженную в данных объемного процесса медленного процесса.
Я бы хотел, чтобы это была условная проверка, которая похожа на этот псевдокод:
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);
Я бы хотел, чтобы он пропустил это, потому что уже есть запись COMPLETE.
Я уверен, что это дублированный вопрос. Но действительно ли это? На этот вопрос так много ответов. Я не уверен, какой из них лучше всего подходит. Посмотрите на все эти примеры, которые я нашел:
Я могу попытаться добавить оператор CASE
, мне сказали, что он эквивалентен оператору IF-THEN-ELSE
. Как сделано в этом примере.
Я могу попытаться использовать оператор SELECT
или COALESCE
в 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/info/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 [email protected] 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();
}
}
}