いくつかのプロジェクトでこれを行った方法は、異なるスキーマでテーブルの2つのコピーを使用することです。つまり、次のようなものです:
CREATE SCHEMA fake WITH AUTHORIZATION dbo;
CREATE SCHEMA standby WITH AUTHORIZATION dbo;
GO
CREATE TABLE dbo.mySummary(<...columns...>);
CREATE TABLE fake.mySummary(<...columns...>);
GO
次に、偽のテーブルを切り捨てて再入力するストアドプロシージャを作成し、トランザクションでスキーマ間でオブジェクトを移動します。
CREATE PROCEDURE dbo.SwapInSummary
AS
BEGIN
SET NOCOUNT ON;
TRUNCATE TABLE fake.mySummary;
INSERT fake.mySummary(<...columns...>)
SELECT <expensive query>;
BEGIN TRANSACTION;
ALTER SCHEMA standby TRANSFER dbo.mySummary;
ALTER SCHEMA dbo TRANSFER fake.mySummary;
ALTER SCHEMA fake TRANSFER standby.mySummary;
COMMIT TRANSACTION;
END
GO
これはおそらく、読み取りの途中でデータを中断することなく、ユーザーに新しいデータが更新されるのを待たせることができる最短の時間です。 (NOLOCKに関連する多くの問題があり、それは確かにコーディングは簡単ですが、あまり望ましくない代替手段になります。)簡潔/明確にするために、エラー処理などを省略しました。データベースを同期するためのスクリプト。両方のテーブルで制約やインデックスなどに同じ名前を付けてください。そうしないと、半分の時間で同期がとれなくなります。手順の最後に、新しいfake.MySummaryテーブルを切り捨てることができますが、スペースがある場合は、データをそこに残して、常に前のバージョンと比較できるようにします。
SQL Server 2005以前は、トランザクション内でsp_renameを使用してまったく同じことを実行していましたが、これをジョブで実行したため、スキーマに切り替えることができてうれしかったです。切り替えたときに、sp_renameからの抑制できない警告が表示されなくなったためです。 SQLServerエージェントの履歴ログを作成します。