使用SQLite可靠的插入

时间:2009-12-06 16:55:34

标签: c# .net sqlite transactions

我正在用C#编写一个需要在多个表中插入数据的程序。第一个插入返回最后一个插入rowid,后者又用于在其他表上执行插入。在伪代码中:

INSERT INTO TableFoo (Col2, Col3, Col4, etc.) VALUES (@Bla2, @bla3, @bla4);

在此插入之后,我立即获得最后一个插入ID:

SELECT last_insert_rowid() AS RowId;

我在datareader中检索RowId列并将其存储在int“RowId”中。 最后,我插入了一些表格,如:

INSERT INTO TableBar (FooId, Col2) VALUES (RowId, @BSomeMoreBla)");

问题:如果可能的话,我想在1个事务中执行这一组插入(和一个select RowId)以防止一些半保存的数据。在这种情况下是否可以使用交易以及首选方式?

SQLite交易? C#的System.Transactions命名空间? 第三种执行原子数据库多插入的方法......?

2 个答案:

答案 0 :(得分:4)

ryber在我的路上帮助了我,但我找到了我自己寻找的解决方案。对于那些可能感兴趣的人,这是我的代码(可能需要一点微调,但是完全合法且可用的代码):

NB。 tbl1具有自动递增PK,tbl2和tbl3通过FK依赖于tbl1的PK。 如果发生异常,则不提交任何查询,就像一个体面的事务应该表现一样;-)。只有在没有错误的情况下执行Commit()时,才会插入整个数组,即使在路中间有一个SELECT。

try {
    transaction = connection.BeginTransaction();

    command = new SQLiteCommand();
    command.Transaction = transaction;
    command.CommandText = "INSERT INTO tbl1 (data) VALUES ('blargh')";
    command.ExecuteNonQuery();

    command = new SQLiteCommand();
    command.Transaction = transaction;
    command.CommandText = "SELECT last_insert_rowid()";
    rowId = Convert.ToInt64(command.ExecuteScalar());

    command = new SQLiteCommand();
    command.Transaction = transaction;
    command.CommandText = "INSERT INTO tbl2 (id, tbl1Id) VALUES (2, @rowId)";
    command.Parameters.Add(new SQLiteParameter("@rowId", rowId));
    command.ExecuteNonQuery();

    command = new SQLiteCommand();
    command.Transaction = transaction;
    command.CommandText = "INSERT INTO tbl3 (id, tbl1Id) VALUES (3, @rowId)";
    command.Parameters.Add(new SQLiteParameter("@rowId", rowId));
    command.ExecuteNonQuery();

    transaction.Commit();
}
catch (Exception ex) {
    if(connection.State == ConnectionState.Open)
        transaction.Rollback();
    MessageBox.Show(ex.Message);
}
finally {
    connection.Close();
    transaction.Dispose();
    command.Dispose();
}

答案 1 :(得分:2)

它应该绝对是一个SQLite事务。你最好的选择是使用像这样的Sqlite数据提供者:http://sqlite.phxsoftware.com/我不确定它自己的基本ADO.Net是否真的能正常工作。

编辑评论:

好的,所以你只想像任何其他ADO交易那样进行交易:

        SqliteCommand command = connection.CreateCommand();
        SqlTransaction transaction = null;

        connection.Open();

        transaction = connection.BeginTransaction();

        command.Transaction = transaction;

        command.CommandText = "Insert bla";
        command.ExecuteNonQuery();

        command.CommandText = "Update bla";
        command.ExecuteNonQuery();

        transaction.Commit();
        connection.Close();

您通常还希望将所有内容放在try / catch中并使用回滚

注意:我不是100%使用该SQlLite命令。看看你的文档......但其余的应该是正确的