Tôi muốn chèn hoặc replace_on_condition. Nếu điều kiện không hài lòng, không chèn hoặc thay thế. Điều này có thể không?Làm thế nào để có điều kiện INSERT HOẶC THAY THẾ một hàng trong SQLite?
Đối với dự án của tôi, tôi hiện có hai quy trình thu thập dữ liệu. Một là nhanh nhưng không bắt tất cả mọi thứ. Người kia chậm nhưng bắt tất cả mọi thứ. Với quy trình nhanh chóng, tôi nhận được dữ liệu gần như trong thời gian thực. Với một chậm, tôi nhận được dữ liệu bằng cách sử dụng một quá trình hàng loạt vào cuối ngày.
Vấn đề của tôi là: đôi khi quá trình nhanh sẽ "Hoàn thành" bản ghi (có nghĩa là nó không còn cần được cập nhật) TRƯỚC KHI quá trình chậm và sau đó trong ngày trong quá trình xử lý hàng loạt, bản ghi "Hoàn thành" sẽ được thay thế bằng bản ghi "Đang chờ xử lý" đã lỗi thời được tìm thấy trong dữ liệu hàng loạt của quá trình chậm.
Những gì tôi muốn là một tấm séc có điều kiện mà đi một cái gì đó giống như giả này:
If(record_is_not_complete or does_not_exist)
{ INSERT or REPLACE; }
Else
{ do_nothing and move_to_the_next; }
Nếu tôi bắt đầu với một tiêu chuẩn INSERT OR REPLACE
dụ:
INSERT OR REPLACE INTO UserProgress (id, status, level)
VALUES (1, 'COMPLETE', 5);
nào nên kết quả trong một hàng trong UserProgress bảng có mục [1, COMPLETE, 5].
Nếu sau đây xảy ra:
INSERT OR REPLACE INTO UserProgress (id, status, level)
VALUES (1, 'PENDING', 4);
Tôi muốn cho nó để bỏ qua điều này, vì đã có một kỷ lục COMPLETE.
Tôi chắc chắn đây là câu hỏi trùng lặp. Nhưng nó thực sự? Có rất nhiều câu trả lời cho câu hỏi này tôi không chắc đó là cách tiếp cận tốt nhất. Hãy xem tất cả các ví dụ mà tôi đã tìm thấy:
Tôi có thể cố gắng thêm tuyên bố CASE
, tôi đã được thông báo là tương đương với tuyên bố IF-THEN-ELSE
. As done in this example.
Tôi có thể cố gắng sử dụng câu lệnh SELECT
hoặc COALESCE
trong VALUES
. As done in this example.
Tôi thậm chí có thể thử sử dụng câu lệnh SELECT WHERE
. As done in this example.
Tôi có thể cố gắng sử dụng câu lệnh LEFT JOIN
. As done in this example.
Điều này thật tuyệt vời cho SQLite. Có vẻ như có nhiều cách để cùng một con mèo. Tôi là một người mới tôi bây giờ bối rối. Tôi không nên sử dụng cách tiếp cận nào.
Tôi đang tìm một giải pháp có thể được thực hiện trong một câu lệnh sql.
* CẬP NHẬT *
Tôi tìm thấy một giải pháp hai giao dịch. Tôi vẫn đang tìm kiếm một giải pháp giao dịch duy nhất.
này hoạt động, nhưng sử dụng hai giao dịch:
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 [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();
}
}
}
Bạn có lẽ nên gọi 'command.Parameters.Clear(); 'trước đó cho-mỗi vòng lặp. – LarsTech