SQLite - como você une tabelas de bancos de dados diferentes?

100

Eu tenho um aplicativo que usa um banco de dados SQLite e tudo funciona como deveria. Agora estou no processo de adicionar novas funcionalidades que requerem um segundo banco de dados SQLite, mas estou tendo dificuldade em descobrir como unir tabelas de bancos de dados diferentes.

Se alguém puder me ajudar com este, eu realmente agradeço!

Edit: Veja esta pergunta para um caso de exemplo que você pode adaptar ao seu idioma ao anexar bancos de dados conforme mencionado na resposta aceita.

Adam Smith
fonte
Como são os bancos de dados? Existe alguma coluna comum que pode ser usada para uni-los? As colunas de cada uma são iguais, de modo que você pode usar um sindicato? sqlite.org/syntaxdiagrams.html
Alex R.
Sim, existem colunas que podem ser unidas usando a palavra-chave USING, pois têm o mesmo nome. Meu problema não é que eu não saiba como entrar, uma vez que meu programa já faz isso com frequência em tabelas no mesmo banco de dados, é que eu não consigo encontrar como vincular os dois bancos de dados, de forma que os dados de um sejam utilizáveis ​​do outro ( como uma junção, por exemplo)
Adam Smith
Exemplo: a primeira base de dados possui uma tabela denominada "agenda", que contém, entre outras colunas, uma coluna de data, um ID de equipe e um número de pista. O segundo banco de dados possui uma tabela que mantém o registro das pontuações inseridas pelos usuários para o jogo de suas equipes. Portanto, esta tabela também possui uma data e um ID de equipe. Quero me juntar a eles usando essas duas colunas para saber em qual pista cada time deve jogar. Existem outras tabelas que terão de ser unidas para outros fins, mas você pode ter uma ideia do que preciso com este exemplo.
Adam Smith

Respostas:

126

Se ATTACH estiver ativado em sua compilação do Sqlite (deve estar na maioria das compilações), você pode anexar outro arquivo de banco de dados à conexão atual usando a palavra-chave ATTACH . O limite no número de dbs que podem ser anexados é uma configuração de tempo de compilação ( SQLITE_MAX_ATTACHED ), atualmente o padrão é 10, mas isso também pode variar de acordo com a compilação que você tem. O limite global é 125.

attach 'database1.db' as db1;
attach 'database2.db' as db2;

Você pode ver todos os bancos de dados conectados com a palavra-chave

.databases

Então você deve ser capaz de fazer o seguinte.

select
  *
from
  db1.SomeTable a
    inner join 
  db2.SomeTable b on b.SomeColumn = a.SomeColumn;

Note-se que "[a] s nomes de banco de dados maine tempsão reservados para o banco de dados primário e banco de dados para armazenar tabelas temporárias e outros objetos de dados temporários. Ambos os nomes de banco de dados existem para cada conexão de banco de dados e não deve ser usado para fixação".

Brian Gideon
fonte
2
O usuário StanleyD observou que não funcionou para ele até que colocou '(aspas simples) em torno do nome do arquivo. Eu encontrei o mesmo.
bkribbs
4

Aqui está um exemplo C # para completar esta questão

/// <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;
    }

}
Dr.Sai
fonte
1

Bem, eu não tenho muita experiência com SQLite você tem que acessar os dois bancos de dados em uma única consulta.

Você pode ter algo como:

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

Em bancos de dados como o SQLServer, você pode acessar outros bancos de dados dessa maneira hierárquica, isso também deve funcionar para o SQLite.

Acho que você pode iniciar uma instância do sqlite com mais de 1 banco de dados!

Yugal Jindle
fonte
Sim, eu vi a documentação do servidor SQL, mas não consegui encontrar a consulta equivalente para SQLite. O problema com essa consulta é que eu uso um gerenciador de drivers para criar minha conexão, então tenho dois objetos de conexão que apontam para os arquivos do banco de dados, mas fazer conn1.table não parece estar funcionando por algum motivo.
Adam Smith