スポンサーリンク
SQL Server

📘 【SQL Server 実践】SELECT TOP 0 * INTO でテーブル構造だけ一瞬でコピーする方法

SQL Server
この記事は約6分で読めます。

SQL Server を使っていると、

  • 既存テーブルと同じ構造のテーブルを作りたい
  • 一時テーブルやアーカイブテーブルをサクッと用意したい
  • CREATE TABLE を手書きするのが面倒

という場面がよくあります。

そんなときに便利なのが SELECT TOP 0 * INTO です。

これは一言でいうと、

データは1件もコピーせず、テーブル構造だけ丸ごとコピーする方法

この記事では、実際に手を動かしながら 「なぜ * を使うのか?」 「何がコピーされて、何がコピーされないのか?」 「運用で気をつけるべき点は?」 までをまとめます。

1. 元テーブルを用意する

まずはサンプルとして在庫テーブルを作ります。

CREATE TABLE dbo.Zaiko (
    ZaikoID   INT IDENTITY(1,1),
    ItemCode  VARCHAR(20),
    ItemName  VARCHAR(100),
    Quantity  INT,
    YM        CHAR(6),
    UpdatedAt DATETIME
);

CREATE INDEX IX_Zaiko_YM ON dbo.Zaiko(YM);

データも少し入れておきます。

INSERT INTO dbo.Zaiko (ItemCode, ItemName, Quantity, YM, UpdatedAt)
VALUES
('A001', 'りんご',   100, '202401', '2024-01-10'),
('A002', 'みかん',   200, '202402', '2024-02-05'),
('A003', 'バナナ',   150, '202403', '2024-03-12'),
('A004', 'ぶどう',   180, '202404', '2024-04-03'),
('A005', 'メロン',   120, '202405', '2024-05-18'),
('A006', 'スイカ',    90, '202406', '2024-06-01'),
('A007', 'パイナップル', 75, '202407', '2024-07-22'),
('A008', 'キウイ',    60, '202408', '2024-08-09'),
('A009', '桃',       130, '202409', '2024-09-14'),
('A010', '梨',       110, '202410', '2024-10-02');

2. SELECT TOP 0 * INTO を実行する

Zaiko と同じ構造のテーブルを作りたい場合は、これだけです。

SELECT TOP 0 *
INTO dbo.Zaiko_Copy
FROM dbo.Zaiko;

実行すると、Zaiko_Copy テーブルが新規作成されます。

3. 本当に「構造だけ」コピーされているか確認する

データ件数

SELECT COUNT(*) FROM dbo.Zaiko;       -- 10件
SELECT COUNT(*) FROM dbo.Zaiko_Copy;  -- 0件

→ データはコピーされていません。

カラム構造

EXEC sp_help 'dbo.Zaiko';
EXEC sp_help 'dbo.Zaiko_Copy';

→ カラム名・データ型・NULL制約・順番は完全一致。

dbo.Zaiko

dbo.Zaiko_Copy

4. SELECT TOP 0 * INTO の仕組み

この SQL はこう動きます。

  • INTO 新テーブル → 新しいテーブルを作る
  • TOP 0 → データは0件(=1件もコピーしない)
  • * → カラム構造をそのまま使う

結果として、

元テーブルと同じ構造の空テーブルが一瞬で作れる

というわけです。

5. あえて *(アスタリスク)を使う理由

✔ 理由1:カラム追加に強い

もしカラムを明示的に書くと、 新しいカラムが追加されるたびに書き直しが必要です。

SELECT TOP 0 ZaikoID, ItemCode, ...  ← 毎回修正が必要

しかし * を使えば、

SELECT TOP 0 * INTO Zaiko_Copy FROM Zaiko;

→ カラム追加しても自動で反映される → ストアドやアプリ側の修正が不要

運用が圧倒的に楽になります。

✔ 理由2:カラム順まで完全一致する

INSERT … SELECT * を使う処理では、 カラム順が一致していることが前提です。

  • を使えば順番も完全一致するため、 アーカイブ処理などで安全に利用できます。

✔ 理由3:CREATE TABLE を手書きするより安全

手書きの CREATE TABLE は、

  • カラム名のタイプミス
  • データ型の書き間違い
  • NULL / NOT NULL のミス

など、事故の温床です。

SELECT TOP 0 * INTO なら 100% 正確にコピー できます。

6. 何がコピーされて、何がコピーされないのか?

コピーされるもの

  • カラム名
  • データ型
  • NULL / NOT NULL
  • カラム順

コピーされないもの(重要)

  • インデックス(非クラスタード含む)
  • PRIMARY KEY
  • UNIQUE
  • FOREIGN KEY
  • CHECK
  • DEFAULT

つまり、SELECT TOP 0 * INTO は「構造だけコピーする」 ということです。

7. インデックスがコピーされないことを確認する

EXEC sp_helpindex 'dbo.Zaiko';
EXEC sp_helpindex 'dbo.Zaiko_Copy';

dbo.Zaikoはインデックスが設定されている。

dbo.Zaiko_Copyにはインデックスの設定がなくなっている。

結果:

  • Zaiko → IX_Zaiko_YM が存在
  • Zaiko_Copy → インデックスなし

→ インデックスはコピーされません。

必要なら後から追加します。

CREATE INDEX IX_Zaiko_Copy_YM ON dbo.Zaiko_Copy(YM);

8. アーカイブ環境などで運用で必ず覚えておくべき注意点

この方法でコピーテーブルを作成するのは、アーカイブやバックアップテーブルを作るときなどが考えられます。

🔥 元テーブルにカラムを追加したら👉 アーカイブテーブルにも同じカラムを追加する必要がある

SELECT TOP 0 * INTO は「最初に作るとき」は便利ですが、 元テーブルにカラムを追加しても、コピーしたテーブルには自動で増えません。アーカイブなどの運用では注意が必要です。

例:

ALTER TABLE Zaiko ADD Location VARCHAR(20);

この場合、アーカイブ側も手動で追加します。

ALTER TABLE Zaiko_Archive ADD Location VARCHAR(20);

これを忘れると:

  • SELECT * のカラム数がズレる
  • アーカイブ処理がエラーになる

という事故につながります。

9. SELECT TOP 0 * INTO が便利な場面

  • アーカイブテーブルの作成
  • 一時テーブルの作成
  • 作業用テーブルの作成
  • 元テーブルとほぼ同じ構造のテーブルを作りたいとき
  • CREATE TABLE を手書きしたくないとき
  • カラム追加に強い仕組みを作りたいとき

まとめ

  • SELECT TOP 0 * INTO は 構造だけコピーする魔法の SQL
  • データはコピーされない
  • インデックス・制約はコピーされない
  • あえて * を使うことで「カラム追加に強い」テーブルが作れる
  • ただし 元テーブルにカラムを追加したら、アーカイブ側にも追加が必要
  • アーカイブや一時テーブルで大活躍

コメント

タイトルとURLをコピーしました