sql >> データベース >  >> RDS >> Sqlserver

SQLServerの一時テーブルの概要

    SQL Serverの一時テーブルは、その名前が示すように、データベースサーバー上に一時的に存在するデータベーステーブルです。一時テーブルには、通常のテーブルのデータのサブセットが一定期間保存されます。

    一時テーブルは、テーブルに多数のレコードがあり、それらのレコードの小さなサブセットを繰り返し操作する必要がある場合に特に役立ちます。このような場合、サブセットをフェッチするためにデータを何度もフィルタリングする代わりに、データを1回フィルタリングして、一時テーブルに格納できます。その後、その一時テーブルに対してクエリを実行できます。一時テーブルは、システムデータベースである「tempdb」内に保存されます。簡単なシナリオで一時データを使用する方法を見てみましょう。

    データの準備

    まず、ダミーデータを用意しましょう。このデータを使用して一時テーブルを作成します。

    データベースサーバーで次のスクリプトを実行します。

    CREATE DATABASE schooldb
    
    CREATE TABLE student
    (
        id INT PRIMARY KEY,
        name VARCHAR(50) NOT NULL,
        gender VARCHAR(50) NOT NULL,
        age INT NOT NULL,
        total_score INT NOT NULL,
        
     )
    
    
    INSERT INTO student 
    
    VALUES (1, 'Jolly', 'Female', 20, 500), 
    (2, 'Jon', 'Male', 22, 545), 
    (3, 'Sara', 'Female', 25, 600), 
    (4, 'Laura', 'Female', 18, 400), 
    (5, 'Alan', 'Male', 20, 500), 
    (6, 'Kate', 'Female', 22, 500), 
    (7, 'Joseph', 'Male', 18, 643), 
    (8, 'Mice', 'Male', 23, 543), 
    (9, 'Wise', 'Male', 21, 499), 
    (10, 'Elis', 'Female', 27, 400);

    上記のSQLスクリプトは、データベース「schooldb」を作成します。このデータベースでは、「student」というテーブルが作成され、いくつかのダミーデータがテーブルに追加されます。

    一時テーブルの作成

    一時テーブルを作成する方法は2つあります。

    方法1

    一時テーブルを作成する最も簡単な方法は、SELECTクエリ内でINTOステートメントを使用することです。学生テーブルのすべての男子学生レコードの名前、年齢、性別を含む一時テーブルを作成しましょう。

    USE schooldb;
    
    SELECT name, age, gender
    INTO #MaleStudents
    FROM student
    WHERE gender = 'Male'
    

    上記のクエリを見てください。ここでは、学生テーブルのすべての男子学生レコードの名前、年齢、性別を格納する一時テーブル「#MaleStudents」を作成しました。一時テーブルを定義するには、SELECTステートメントの後にINTOステートメントを使用します。一時テーブルの名前はハッシュ(#)で始まる必要があります。

    ここで、このテーブルがどこにあるかを確認します。 「オブジェクトエクスプローラー->データベース->システムデータベース->tempdb->一時テーブル」に移動します。一時テーブル名と識別子が表示されます。次の図を見てください:

    テーブル名の最後にある「000000000006」について疑問に思われるかもしれません。これは一意の識別子です。複数のデータベース接続で同じ名前の一時テーブルを作成できるため、異なる接続で作成された一時テーブルを区別するために、データベースサーバーはこの一意の識別子を最後に自動的に追加します。

    一時テーブルを作成したのと同じ接続を介して、一時テーブルに対して操作を実行できます。したがって、「#MaleStudents」テーブルを作成したのと同じクエリウィンドウで、次のクエリを実行します。

    SELECT * FROM #MaleStudents

    以来、#MaleStudentsテーブルには、すべての男子生徒の名前、年齢、性別が含まれています。上記のクエリは、次の結果をフェッチします。

    [テーブルID=15 /]

    新しい接続を作成するには、「SQLServerManagementStudio」で新しいクエリウィンドウを開くだけです。ここで、前の接続を開いたままにして、新しいクエリウィンドウ(新しい接続)でメソッド2を使用して別の「MaleStudents」テーブルを作成します。

    方法2

    2番目の方法は、通常のテーブルの作成に似ています。次のクエリを見てください。ここでも、#MaleStudents一時テーブルを作成します。このクエリは新しい接続で実行する必要があることに注意してください。

    USE schooldb;
    
    CREATE TABLE #MaleStudents
    (
    	name VARCHAR(50),
    	age int,
    	gender VARCHAR (50)
    
    )
    
    INSERT INTO #MaleStudents
    SELECT name, age, gender
    FROM student
    WHERE gender = 'Male'
    

    ここで、上記のクエリを実行すると、tempdb内に一意の識別子が異なる2つの#MaleStudents一時テーブルが表示されます。これは、これら2つのテーブルが2つの異なる接続によって作成されているためです。次のスクリーンショットを見てください。

    グローバル一時テーブル

    ここで言及するのは適切ですが、一時テーブルには、その一時テーブルを作成した接続にのみアクセスできます。他の接続にはアクセスできません。ただし、開いているすべての接続にアクセスできる一時テーブルを作成できます。このような一時テーブルは、グローバル一時テーブルと呼ばれます。グローバル一時テーブルの名前は、二重ハッシュ記号(##)で始まります。学生テーブルのすべての女子学生のレコードを含むグローバル一時テーブルを作成しましょう。

    USE schooldb;
    
    SELECT name, age, gender
    INTO ##FemaleStudents
    FROM student
    WHERE gender = 'Female'
    

    これで、開いている接続のいずれかから##FemaleStudentsテーブルにアクセスできます。

    一時テーブルの削除

    SQL Serverで一時テーブルを削除するには、自動削除と手動削除の2つの方法があります。

    自動削除

    テーブルを作成した接続が閉じられると、一時テーブルは自動的に削除されます。または、変更を保存せずに一時テーブルを作成したクエリウィンドウを閉じると、テーブルが閉じられます。接続がグローバルテーブルに対していくつかのクエリを実行している場合、グローバルテーブルを削除する前に、それらのクエリを最初に完了する必要があります。

    手動によるテーブルの削除

    DROP TABLEステートメントを使用すると、接続を閉じずに手動でテーブルを削除できます。ただし、ステートメントは、実際にテーブルを作成した接続によって実行される必要があることに注意してください。次のクエリを見てください:

    DROP TABLE #MaleStudents

    これは、通常のテーブルを削除することに似ています。

    一時テーブルとストアドプロシージャ

    以前、一時テーブルには、それを作成した接続内でローカルにのみアクセスできることを学びました。その規則には1つの例外があります。ストアドプロシージャを作成しているときは、他の接続の一時テーブルにもアクセスできます。

    2つの異なる接続を使用して2つのストアドプロシージャを作成しましょう。最初のストアドプロシージャは#MaleStudentsテーブルにデータを挿入し、2番目のストアドプロシージャはテーブルからデータを選択します。

    新しい接続を作成します。 SQL Server Management Studioを使用している場合は、新しいクエリウィンドウを開くことで使用できます。新しいクエリウィンドウで次のSQLスクリプトを実行します。

    Create Procedure spInsertStudent
        (@Name Varchar(50), @Age int,  @Gender Varchar(50))
    As
    Begin
        Insert Into #MaleStudents
        Values (@Name, @Age, @Gender)
    End
    

    これで、レコードを#MaleStudent一時テーブルに挿入するストアドプロシージャが作成されました。この接続では#MaleStudentは作成されませんでしたが、レコードを挿入してアクセスしていることに注意してください。これは、ストアドプロシージャを作成するときに、テーブルを作成した接続以外の接続から一時テーブルにアクセスできるためです。上記のクエリを実行すると、SQLServerがエラーをスローしないことがわかります。

    同様に、新しい接続を開き、その中に次のストアドプロシージャを作成します。

    CREATE PROCEDURE spListStudent
    AS
    BEGIN
    
    	SELECT * FROM #MaleStudents
    	ORDER BY name
    END
    

    上記のストアドプロシージャは、#MaleStudents一時テーブルからすべてのレコードを選択します。ここでも、テーブルを作成しなかった接続内の一時テーブルにアクセスしています。

    ここで注意が必要な部分があります。ストアドプロシージャを作成するときに別の接続内の一時テーブルにアクセスすることはできますが、別の接続内でストアドプロシージャを「実行」するときに一時テーブルにアクセスすることはできません。一時テーブルにアクセスするストアドプロシージャを実行するには、一時テーブルを作成した接続内にいる必要があります。

    したがって、#MaleStudentsテーブルを作成した接続内で次のクエリを実行します。

    EXECUTE spInsertStudent Bradley, 45, Male
    Execute spListStudent
    

    ここで、最初のストアドプロシージャは、名前がBradley、age:45、gender:Maleの新しい学生レコードを#MaleStudentsテーブルに挿入します。 2番目のストアドプロシージャは、名前の昇順で#MaleStudentsテーブルからすべてのレコードを選択します。上記のストアドプロシージャの出力は次のようになります。

    [テーブルID=16 /]

    上記の選択したレコードに、新しく挿入されたレコードがはっきりと表示されます。

    関連項目:

    SQLServerのテーブル変数のパフォーマンス

    SQLServerでの共通テーブル式の紹介


    1. MySQLエンティティ属性値スキーマをピボットする方法

    2. 例を使用してSQLで連結する方法について学ぶ

    3. MySQLから整数列と数値列をPHPの整数と数値として返すにはどうすればよいですか?

    4. オラクルのempテーブルで上位3つの最高給与を見つける方法は?