web-dev-qa-db-fra.com

Interrogation des données en joignant deux tables dans deux bases de données sur des serveurs différents

Il y a deux tables dans deux bases de données différentes sur des serveurs différents, je dois les joindre afin de faire quelques requêtes. Quelles sont mes options? Que devrais-je faire?

83
Kashif

Vous devrez utiliser sp_addlinkedserver pour créer un lien de serveur. Voir la documentation référence pour l’utilisation. Une fois le lien de serveur établi, vous construirez la requête normalement, en préfixant simplement le nom de la base de données à l'autre serveur. C'EST À DIRE:

-- FROM DB1
SELECT *
FROM [MyDatabaseOnDB1].[dbo].[MyTable] tab1
    INNER JOIN [DB2].[MyDatabaseOnDB2].[dbo].[MyOtherTable] tab2
        ON tab1.ID = tab2.ID

Une fois le lien établi, vous pouvez également utiliser OPENQUERY pour exécuter une instruction SQL sur le serveur distant et ne vous transférer que les données. Cela peut être un peu plus rapide et permettre au serveur distant d’optimiser votre requête. Si vous mettez les données en cache dans une table temporaire (ou en mémoire) sur DB1 dans l'exemple ci-dessus, vous pourrez alors l'interroger comme si vous rejoigniez une table standard. Par exemple:

-- Fetch data from the other database server
SELECT *
INTO #myTempTable
FROM OPENQUERY([DB2], 'SELECT * FROM [MyDatabaseOnDB2].[dbo].[MyOtherTable]')

-- Now I can join my temp table to see the data
SELECT * FROM [MyDatabaseOnDB1].[dbo].[MyTable] tab1
    INNER JOIN #myTempTable tab2 ON tab1.ID = tab2.ID

Consultez la documentation pour OPENQUERY pour voir d'autres exemples. L'exemple ci-dessus est assez artificiel. J'utiliserais certainement la première méthode dans cet exemple spécifique, mais la deuxième option utilisant OPENQUERY peut économiser du temps et des performances si vous utilisez la requête pour filtrer certaines données.

68
Scott Anderson

Essaye ça:

SELECT tab2.column_name  
FROM  [DB1.mdf].[dbo].[table_name_1] tab1 INNER JOIN [DB2.mdf].[dbo].[table_name_2]  tab2   
    ON tab1.col_name = tab2.col_name

Si votre base de données n’autorise pas un serveur lié, vous pouvez utiliser OPENROWSET. Books Online vous fournira la syntaxe dont vous avez besoin.

4
HLGEM

Du point de vue de l'entreprise, la meilleure pratique consiste à créer une copie en miroir de la table de base de données dans votre base de données, puis à simplement la mettre à jour avec une tâche/proc chaque heure.

2
Dave

Une jointure de deux tables est mieux faite par un SGBD, donc cela devrait être fait de cette façon. Vous pouvez mettre en miroir la plus petite table ou un sous-ensemble de celle-ci sur l'une des bases de données, puis les joindre. On pourrait être tenté de le faire sur un serveur ETL comme Informatica, mais je suppose que ce n’est pas conseillé si les tables sont énormes.

1
Abdulmoeed

Si l'option de liaison de base de données n'est pas disponible, vous pouvez également associer les tables via ODBC à quelque chose tel que les rapports MS Access ou Crystal et effectuer la jointure à cet endroit.

1
Holdfast

J'ai essayé ce code ci-dessous et ça fonctionne bien

SELECT        TimeTrackEmployee.StaffID
FROM            dbo.tblGBSTimeCard AS GBSTimeCard INNER JOIN
                         TimeTrak.dbo.tblEmployee AS TimeTrackEmployee ON GBSTimeCard.[Employee Number] = TimeTrackEmployee.GBSStaffID
1
Quang Ninh

Alors que j’avais du mal à joindre ces deux tables, je n’ai pas eu la peine de faire exactement ce que je voulais en ouvrant les deux bases de données distantes en même temps. MySQL 5.6 (php 7.1) et l'autre MySQL 5.1 (php 5.6)

//Open a new connection to the MySQL server
$mysqli1 = new mysqli('server1','user1','password1','database1');
$mysqli2 = new mysqli('server2','user2','password2','database2');

//Output any connection error
if ($mysqli1->connect_error) {
    die('Error : ('. $mysqli1->connect_errno .') '. $mysqli1->connect_error);
} else { 
echo "DB1 open OK<br>";
}
if ($mysqli2->connect_error) {
    die('Error : ('. $mysqli2->connect_errno .') '. $mysqli2->connect_error);
} else { 
echo "DB2 open OK<br><br>";
}

Si vous obtenez ces deux OK à l'écran, les deux bases de données sont ouvertes et prêtes. Ensuite, vous pouvez procéder pour faire vos requêtes.

$results = $mysqli1->query("SELECT * FROM video where video_id_old is NULL");
    while($row = $results->fetch_array()) {
        $theID = $row[0];
        echo "Original ID : ".$theID." <br>";
        $doInsert = $mysqli2->query("INSERT INTO video (...) VALUES (...)");
        $doGetVideoID = $mysqli2->query("SELECT video_id, time_stamp from video where user_id = '".$row[13]."' and time_stamp = ".$row[28]." ");
            while($row = $doGetVideoID->fetch_assoc()) {
                echo "New video_id : ".$row["video_id"]." user_id : ".$row["user_id"]." time_stamp : ".$row["time_stamp"]."<br>";
                $sql = "UPDATE video SET video_id_old = video_id, video_id = ".$row["video_id"]." where user_id = '".$row["user_id"]."' and video_id = ".$theID.";";
                $sql .= "UPDATE video_audio SET video_id = ".$row["video_id"]." where video_id = ".$theID.";";
                // Execute multi query if you want
                if (mysqli_multi_query($mysqli1, $sql)) {
                    // Query successful do whatever...
                }
            }
    }
// close connection 
$mysqli1->close();
$mysqli2->close();

J'essayais de faire des jointures mais depuis que j'ai ouvert ces deux bases de données, je peux faire des requêtes en changeant simplement la connexion $mysqli1 ou $mysqli2 

Cela a fonctionné pour moi, j'espère que ça aide ... À la vôtre

0
Luis H Cabrejo

Vous pouvez essayer ce qui suit:

select customer1.Id,customer1.Name,customer1.city,CustAdd.phone,CustAdd.Country
from customer1
inner join [EBST08].[Test].[dbo].[customerAddress] CustAdd
on customer1.Id=CustAdd.CustId
0
sohan yadav

Les noms de base de données codés en dur ne sont peut-être pas la meilleure approche dans une requête SQL. Ainsi, ajouter des synonymes serait une meilleure approche. Les bases de données ne portent pas toujours le même nom dans plusieurs environnements de transfert. Ils pourraient être composés de postfixes tels que PROD, UAT, SIT, QA, etc. Soyez donc conscient des requêtes codées en dur et rendez-les plus dynamiques.

Approche n ° 1: Utilisez des synonymes pour lier des tables entre des bases de données sur le même serveur.

Approche n ° 2: Recueillez les données séparément de chaque base de données et joignez-les à votre code. Vos chaînes de connexion à la base de données peuvent faire partie de la configuration de votre serveur d'applications via une base de données ou un fichier de configuration.

0
Niklas Henricson