異なるサーバー上の2つの異なるデータベースに2つのテーブルがあり、クエリをほとんど行わないようにそれらを結合する必要があります。どのようなオプションがありますか?私は何をすべきか?
サーバーリンクを作成するには、sp_addlinkedserver
を使用する必要があります。使用方法については、 リファレンスドキュメント を参照してください。サーバーリンクが確立されると、データベース名に他のサーバーのプレフィックスを付けるだけで、通常どおりクエリを作成します。 I.E:
-- FROM DB1
SELECT *
FROM [MyDatabaseOnDB1].[dbo].[MyTable] tab1
INNER JOIN [DB2].[MyDatabaseOnDB2].[dbo].[MyOtherTable] tab2
ON tab1.ID = tab2.ID
リンクが確立されると、OPENQUERY
を使用してリモートサーバーでSQLステートメントを実行し、データのみをユーザーに戻すこともできます。これは少し速くなる可能性があり、リモートサーバーがクエリを最適化できるようにします。上記の例でDB1
の一時(またはメモリ内)テーブルにデータをキャッシュすると、標準テーブルを結合するのと同じようにクエリを実行できます。例えば:
-- 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
OPENQUERYのドキュメント をチェックして、他の例を参照してください。上記の例はかなり不自然です。この特定の例では間違いなく最初の方法を使用しますが、OPENQUERY
を使用する2番目のオプションでは、クエリを使用してデータをフィルター処理すると、時間とパフォーマンスを節約できます。
これを試して:
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
リンクサーバーがdbaで許可されていない場合は、OPENROWSETを使用できます。 Books Onlineは、必要な構文を提供します。
実用的な企業の観点から見ると、ベストプラクティスはデータベース内のデータベーステーブルのミラーコピーを作成し、タスク/プロシージャに1時間ごとにデルタを更新させることです。
2つのテーブルの結合はDBMSによって最適に行われるため、そのようにする必要があります。小さいテーブルまたはそのサブセットをデータベースの1つにミラーリングしてから、それらを結合できます。 informaticaのようなETLサーバーでこれを実行したいと思うかもしれませんが、テーブルが巨大な場合はお勧めできません。
データベースリンクオプションが利用できない場合、別の方法として、テーブルをODBCを介してMS AccessやCrystalレポートなどにリンクし、そこで結合することができます。
これらの2つのテーブルを結合するのに苦労していましたが、両方のリモートデータベースを同時に開くことで、必要なことを正確に行うことができました。 MySQL 5.6(php 7.1)およびその他の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>";
}
画面にこれらの2つのOKが表示された場合、両方のデータベースが開いて準備ができています。その後、クエリの実行に進むことができます。
$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();
私はいくつかの結合を行おうとしていましたが、これらの2つのDBを開いたので、接続$mysqli1
または$mysqli2
を変更するだけでクエリをやり取りできます
それは私のために働いた、私はそれが役立つことを願っています...乾杯
次を試すことができます:
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
私は以下のこのコードを試してみましたが、うまく機能しています
SELECT TimeTrackEmployee.StaffID
FROM dbo.tblGBSTimeCard AS GBSTimeCard INNER JOIN
TimeTrak.dbo.tblEmployee AS TimeTrackEmployee ON GBSTimeCard.[Employee Number] = TimeTrackEmployee.GBSStaffID
データベース名をハードコードすることは、SQLクエリ内で常に最良のアプローチではありません。したがって、同義語を追加する方が適切なアプローチです。データベースが複数のステージング環境で同じ名前を持っているとは限りません。これらは、PROD、UAT、SIT、QAなどの接尾辞で構成される場合があります。そのため、ハードコーディングされたクエリに注意し、それらをより動的にします。
アプローチ#1:シノニムを使用して、同じサーバー上のデータベース間でテーブルをリンクします。
アプローチ#2:各データベースから個別にデータを収集し、コードに結合します。データベース接続文字列は、データベースまたは構成ファイルのいずれかを介したアプリサーバー構成の一部である場合があります。