Knowledge Notebook
一覧に戻る

SQL Serverで上位バージョンから下位バージョンへデータを移行・復元する代替手段まとめ(2022→2016等)

SQL Serverの運用において、「開発環境や移行先のSQL Serverのバージョンが古い(例:SQL Server 2016)」一方で、「本番環境や手元の環境のバージョンが新しい(例:SQL Server 2022)」というケースは珍しくありません。しかし、SQL Serverでは上位互換性はサポートされておらず、上位バージョンのバックアップ(.bak)を下位バージョンに直接復元することはできません。

本記事では、この制限が発生する理由と、それを乗り越えてデータをダウングレード移行・復元するための3つの代表的な代替手段を解説します。

1. バックアップ (.bak) ファイルのリストアが失敗する理由

SQL Serverは下位互換性を重視して設計されています。例えば、SQL Server 2016で作成したバックアップファイルをSQL Server 2022へ復元することは標準でサポートされています。しかし、逆の上位互換性(新しいバージョンから古いバージョンへ)は物理構造の違いからサポートされていません。

SQL Serverのデータベースには内部バージョン番号(内部データベースバージョン)が存在します。

  • SQL Server 2022:内部バージョン 957
  • SQL Server 2016:内部バージョン 852

SQL Server 2016 (852) は、自分より新しい内部バージョン 957 のデータベースファイルの構造を解釈できないため、バックアップファイルをリストアしようとしたり、MDF/LDFファイルを直接アタッチしようとしたりすると、以下のようなエラーが発生して失敗します。

エラーメッセージの例:
データベース 'DatabaseName' はバージョン 957 ですが、このサーバーはバージョン 852 以前をサポートしています。このデータベースは復元またはアタッチできません。

※データベースの「互換性レベル」を「130(SQL Server 2016)」に下げていても、物理ファイルの内部バージョン自体は移行元の 957 のままになるため、やはりバックアップ復元はできません。

2. 代替手段①:SSMS「スクリプトの生成」ウィザード

最も手軽で標準的な手段は、SQL Server Management Studio (SSMS) を使用して、テーブル構造(スキーマ)と格納されているデータをインサート文のスクリプトとして出力し、移行先で実行する方法です。小〜中規模(数十万レコード程度まで)のデータベースに最適です。

実行手順

  1. 移行元(2022)のデータベースを右クリックし、[タスク] > [スクリプトの生成] を選択します。
  2. スクリプトを作成するオブジェクト(通常はデータベース全体、または特定のテーブル)を選択します。
  3. 「スクリプトの保存または公開」画面で [詳細設定] ボタンをクリックします。
  4. 詳細設定の中で、以下の2項目を必ず変更します。
    • データベースエンジンの種類に対するスクリプト: 移行先のバージョン(例: SQL Server 2016)に設定
    • スクリプトを作成するデータの種類: スキーマとデータ に設定
  5. 出力されたSQLファイルを、移行先(2016)のSSMSで接続して実行します。

メリット・デメリット

  • メリット: SSMSだけで完結し、トリガーやインデックス、外部キーなどの関連情報も自動でスクリプト化されます。
  • デメリット: データ量が大きい(数GB以上)場合、生成されるSQLファイルのサイズが極端に巨大化し、移行先で開こうとした際にSSMSがメモリ不足(Out of Memory)でフリーズする原因になります(この場合は sqlcmd コマンドラインツールで実行するか、別の手段を取る必要があります)。

3. 代替手段②:BACPAC(データ層アプリケーション)のインポート/エクスポート

BACPACは、スキーマ定義(XML形式)とデータ(BACPAC形式)をパッケージ化した1つのファイル(.bacpac)として出力・移行する機能です。Azure SQL Databaseへの移行などで広く使われますが、オンプレミス間での移行でも有効です。

実行手順

  1. 移行元(2022)のデータベースを右クリックし、[タスク] > [データ層アプリケーションのエクスポート] を選択します。
  2. 出力先(.bacpacファイル)を指定して実行します。
  3. 移行先(2016)のオブジェクトエクスプローラーで [データベース] フォルダを右クリックし、[データ層アプリケーションのインポート] を選択します。
  4. 作成した.bacpacファイルを指定し、インポートを実行します。

注意点

  • エクスポート時にスキーマチェックが厳密に行われるため、2022でしか使えないスキーマや構文(新しい計算列など)が存在する場合、エクスポート処理そのものがエラーで停止します。この場合は、移行元のスキーマをあらかじめクリーンアップする必要があります。

4. 代替手段③:インポートおよびエクスポート ウィザード (SSIS)

データ量が非常に大きい(数百万レコード以上)場合には、データ転送のパフォーマンスが高い「インポートおよびエクスポートウィザード」が推奨されます。

実行手順

  1. あらかじめ移行先(2016)にテーブルの構造(スキーマのみ)を作成しておきます。(上記「スクリプトの生成」で「スキーマのみ」を出力して実行しておくと簡単です)。
  2. 移行元(2022)のデータベースを右クリックし、[タスク] > [データのエクスポート] を選択します。
  3. データソースに「移行元のSQL Server」を設定し、変換先に「移行先(2016)のSQL Server」を設定します。
  4. コピーするテーブルを選択し、必要に応じてマッピング情報を調整した上で、データコピーを実行します。

メリット

  • データ転送速度が非常に速く、メモリ制限にかかりにくいため、大規模なデータ移行に向いています。また、外部キー制約やトリガーなどの依存関係を一時的に考慮せずにデータだけを流し込むことができるため、順序依存のエラーが防げます。

5. SQL Server 2022から2016への移行時の注意点

上位から下位への移行においては、下位バージョンでサポートされていない機能が移行元で使われている場合にエラーが発生します。特に 2022 から 2016 への移行では以下の点に注意してください。

  • 新機能や関数の使用制限: SQL Server 2022で追加された新しいT-SQL関数(例: GREATEST, LEAST, STRING_SPLIT の第3引数など)を使用しているストアドプロシージャやビュー、計算列が存在する場合、2016で実行すると「オブジェクト名が無効」または構文エラーになります。
  • JSONサポート: SQL Server 2016でもJSONの基本機能(JSON_VALUE など)は利用できますが、2022で追加された新しいJSON関数(JSON_OBJECT, JSON_ARRAY など)は使えません。
  • ページ・行圧縮機能: SQL Server 2016では、圧縮機能(Page/Row Compression)がEnterpriseエディション専用でしたが、2016 SP1以降であればStandardエディションでも利用可能になっています。移行先サーバーのService Pack適用状況に注意してください。

6. まとめ

SQL Serverの上位から下位への移行では、データ規模や移行環境に合わせて最適な方法を選ぶことが重要です。

  • 数万〜数十万行程度(小〜中規模): 簡単な [スクリプトの生成(スキーマとデータ)] を選択。
  • クラウドや複数DBへの展開がある場合: 標準化された [BACPACのエクスポート/インポート] を選択。
  • 数百万行以上(大規模): 空のスキーマを作成した後に [インポートおよびエクスポートウィザード(エクスポート)] を選択。

移行先のバージョンで非推奨となった機能やサポート外の構文がないか、移行前にスキーマを念入りにチェックしましょう。


参考URL