SQLite - 如何连接来自不同数据库的表?

125
我有一个使用SQLite数据库的应用程序,一切都正常运行。我现在正在添加需要第二个SQLite数据库的新功能,但我很难弄清楚如何连接来自不同数据库的表格。
如果有人能帮助我解决这个问题,我将不胜感激!
编辑:请参考此问题以获取示例案例,您可以根据答案中提到的附加数据库适用于您的语言。

数据库是什么样的?有哪些常见列可以用来连接它们?每个表的列是否相同,以便可以使用 UNION 操作符?http://www.sqlite.org/syntaxdiagrams.html - Alex R.
是的,有一些列可以使用USING关键字进行连接,因为它们的名称相同。我的问题不在于我不知道如何连接,因为我的程序已经经常在同一数据库中的表上执行此操作,而是我似乎找不到如何链接两个数据库,以便从另一个数据库中使用其数据(例如像连接一样)。 - Jumbala
第一个数据库有一个名为“schedule”的表,其中包含日期列、团队ID和车道号等列。第二个数据库有一张表,用于跟踪用户为其团队比赛输入的得分。因此,该表也具有日期和团队ID。我想使用这两列将它们连接起来,以了解每个团队应该在哪条车道上比赛。还有其他表需要连接以实现其他目的,但您可以从这个例子中了解到我需要什么。 - Jumbala
3个回答

168
如果你的Sqlite版本中已经启用ATTACH(在大部分版本中都应该启用),你可以使用ATTACH关键字将另一个数据库文件附加到当前连接。可附加的db数量限制是编译时设置(SQLITE_MAX_ATTACHED),默认为10,但这也可能因你所使用的版本而有所不同。全局限制为125。
attach 'database1.db' as db1;
attach 'database2.db' as db2;

您可以使用关键字查看所有已连接的数据库

.databases

然后,您应该能够完成以下操作。
select
  *
from
  db1.SomeTable a
    inner join 
  db2.SomeTable b on b.SomeColumn = a.SomeColumn;

请注意,"[t]he database names main and temp are reserved for the primary database and database to hold temporary tables and other temporary data objects. Both of these database names exist for every database connection and should not be used for attachment"。

3
用户 StanleyD 指出,直到他在文件名周围加上 '(单引号)时才起作用。我也发现了相同的情况。 - bkribbs
在使用attach语句后,我可以选择不同的主数据库吗? - mvorisek

4
这里有一个C#示例以完成此问题。
/// <summary>
/// attachSQL = attach 'C:\\WOI\\Daily SQL\\Attak.sqlite' as db1 */
/// path = "Path of the sqlite database file
/// sqlQuery  = @"Select A.SNo,A.MsgDate,A.ErrName,B.SNo as BSNo,B.Err as ErrAtB from Table1 as A 
///                    inner join db1.Labamba as B on 
///                    A.ErrName = B.Err";
/// </summary>
/// <param name="attachSQL"></param>
/// <param name="sqlQuery"></param>
public static DataTable GetDataTableFrom2DBFiles(string attachSQL, string sqlQuery)
{
    try
    {
        string conArtistName = "data source=" + path + ";";
        using (SQLiteConnection singleConnectionFor2DBFiles = new SQLiteConnection(conArtistName))
        {
            singleConnectionFor2DBFiles.Open();
            using (SQLiteCommand AttachCommand = new SQLiteCommand(attachSQL, singleConnectionFor2DBFiles))
            {
                AttachCommand.ExecuteNonQuery();
                using (SQLiteCommand SelectQueryCommand = new SQLiteCommand(sqlQuery, singleConnectionFor2DBFiles))
                {
                    using (DataTable dt = new DataTable())
                    {
                        using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(SelectQueryCommand))
                        {
                            adapter.AcceptChangesDuringFill = true;
                            adapter.Fill(dt);
                            return dt;
                        }
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Use Process Exception method An error occurred");
        return null;
    }

}

1
这个可行 - 谢谢。但是顺便说一下,我认为我们不需要那么多嵌套的using语句。 - topsail

2

嗯,我对SQLite没有太多经验,但你需要在一个查询中访问两个数据库。

你可以像这样:

select name from DB1.table1 as a join DB2.table2 as b where a.age = b.age;

在像SQLServer这样的数据库中,您可以以分层方式访问其他数据库,这对于SQLite也应该适用。
我认为您可以使用一个实例来初始化多个sqlite数据库!

是的,我看了SQL Server的文档,但找不到SQLite的等效查询。那个查询的问题在于我使用drivermanager创建我的连接,所以我有两个连接对象指向数据库文件,但是执行conn1.table似乎出了一些问题。 - Jumbala

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