合并两个SQLite数据库文件(C# .NET)

6
我正在使用C#/.NET和SQLite的C#包装器。我尝试将两个SQLite数据库合并在一起,同时排除重复项。
我找到了这个链接,它被几个不同的论坛问题引用:http://old.nabble.com/Attempting-to-merge-large-databases-td18131366.html 我尝试了下面的查询,按照我提供的链接进行了结构化,但结果会导致异常,数据库根本没有合并,并且原始数据库没有改变。
attach 'c:\test\b.db3' as toMerge;   
insert into AuditRecords select * from toMerge.AuditRecords; 

这是我的查询代码。

public void importData(String fileLoc)
    {
        SQLiteTransaction trans;
        string SQL = "ATTACH '" + fileLoc + "' AS TOMERGE";
        SQLiteCommand cmd = new SQLiteCommand(SQL);
        cmd.Connection = connection;
        connection.Open();
        trans = connection.BeginTransaction();
        int retval = 0;
        try
        {
            retval = cmd.ExecuteNonQuery();
        }
        catch (Exception)
        {
            trans.Rollback();
            MessageBox.Show("An error occurred, your import was not completed.");
        }
        finally
        {
            trans.Commit();
            cmd.Dispose();
            connection.Close();
        }

        SQL = "INSERT INTO SUBCONTRACTOR SELECT * FROM TOMERGE.SUBCONTRACTOR";
        cmd = new SQLiteCommand(SQL);
        cmd.Connection = connection;
        connection.Open();
        trans = connection.BeginTransaction();
        retval = 0;
        try
        {
            retval = cmd.ExecuteNonQuery();
        }
        catch (Exception)
        {
            trans.Rollback();
            MessageBox.Show("An error occurred, your import was not completed.");
        }
        finally
        {
            trans.Commit();
            cmd.Dispose();
            connection.Close();
        }
    }

我的问题是,我做错了什么?有人熟悉插入命令吗?我不确定它是否会排除重复项,这是我需要的。
1个回答

11

在SQLite中附加数据库时,需要在单个连接/事务中执行每个语句(无论是插入、更新、删除)。不要在两者之间关闭连接。它应该在一个事务中完成。

尝试这样做

public void importData(String fileLoc)
        {
            string SQL = "ATTACH '" + fileLoc + "' AS TOMERGE";
            SQLiteCommand cmd = new SQLiteCommand(SQL);
            cmd.Connection = connection;
            connection.Open();
            int retval = 0;
            try
            {
                retval = cmd.ExecuteNonQuery();
            }
            catch (Exception)
            {
                MessageBox.Show("An error occurred, your import was not completed.");
            }
            finally
            {
                cmd.Dispose();
            }

            SQL = "INSERT INTO SUBCONTRACTOR SELECT * FROM TOMERGE.SUBCONTRACTOR";
            cmd = new SQLiteCommand(SQL);
            cmd.Connection = connection;
            retval = 0;
            try
            {
                retval = cmd.ExecuteNonQuery();
            }
            catch (Exception)
            {
                MessageBox.Show("An error occurred, your import was not completed.");
            }
            finally
            {
                cmd.Dispose();
                connection.Close();
            }
        }

太好了!这个方法可行,但是它不能移除重复项。你有什么处理重复项的建议吗?除了插入命令,是否还有其他命令可以使用?再次感谢你的帮助。 - CODe
6
为避免重复,您可以像这样比较两个表格:{ SQL = "INSERT INTO SUBCONTRACTOR SELECT * FROM TOMERGE.SUBCONTRACTOR WHERE [YOUR_UNIQUE_ID] NOT IN (SELECT [YOUR_UNIQUE_ID] FROM SUBCONTRACTOR) }。 (注:这是一段SQL语句,用于在将一个子承包商表格与另一个表格合并时,避免插入重复数据。具体方法是通过比较唯一ID来确定哪些数据需要插入到目标表格中。) - Binil
@Binil,我按照你的答案操作了,但是无法使其工作。它一直显示“connection未定义”。我已经发布了一个问题,询问是否有更现代或更好的解决方案。如果您能帮助我解决这个问题或回答我的问题,我将不胜感激 :) https://stackoverflow.com/questions/59115084/merging-two-sqlite-databases-c?noredirect=1#comment104467937_59115084 - Jacob Cook
2
@JacobCook StackOverflow上的许多代码答案并不完整,它们只是为特定问题提供解决方案的演示。它们通常不包含其他必要的代码。通常假设编码人员熟悉特定问题周围的细节。您的问题是关于合并数据库的,因此假设您知道如何连接(即打开)数据库。在此代码中,connection变量显然未定义,因此必须在其他地方定义和打开。如果您不理解原因,则需要学习C#变量和sqlite连接。 - C Perkins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接