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

SQL Server DELETE –少し高度なシナリオでテーブルから1つ以上の行を削除する

    現在の記事では、テーブルから1つ以上のレコード(行)を削除するためのDELETEステートメントの少し高度な使用に焦点を当てています。主に初心者を対象としていますが、そのヒントはすべてのデータベーススペシャリストに役立つ可能性があります。

    前提条件:DELETEステートメントの基本シナリオ

    Deleteステートメントの基本的な使用法にまだ慣れていない場合は、前の記事「SQL Server DELETE –テーブルからの1つ以上の行の削除」を確認することをお勧めします。この記事では、次の側面に焦点を当てています。

    1. サンプルデータベースの設定。
    2. サンプルデータベースに対してSQLスクリプトを実行します。
    3. サンプルデータベースにテーブルを作成し、そこにデータを挿入します。
    4. テーブルからすべての行を削除します。
    5. 条件に基づいてテーブルから1つ以上の行を削除します。
    6. 複数の条件に基づいてテーブルから1つ以上の行を削除します。

    これらのデータは、Deleteステートメントの少し高度な使用法に進む前に把握することが重要です。したがって、これまでに必要な背景がない場合は、その記事を確認してください。

    DELETEステートメントのやや高度なシナリオ

    他のウォークスルーと同様に、最初にサンプルデータベースを設定して、スクリプトを安全に実行することをテストする必要があります。

    サンプルデータベースのセットアップに関するヒント

    まず、SQL ServerDeveloperEditionをローカルのマシンにインストールすることを強くお勧めします。学習とテストの目的に適しています。

    SQLServer開発者版のダウンロード

    サンプルデータベースのセットアップ(WatchesDelSample)

    WatchesDelSampleというデータベースを設定します。このデータベースには、次の3つのテーブルが含まれています。

    1. 見る。
    2. 色。
    3. WatchType。

    ウォッチテーブルがメインです。時計の名前、色、種類が含まれています。タイプと色の両方に関する情報は、2つの参照テーブルから取得されます。 およびWatchType 外部キーを介して接続されています。

    次のスクリプトを使用してサンプルデータベースを設定します。

    -- Create sample database WatchesDelSample
    USE MASTER
    GO
    
    CREATE DATABASE WatchesDelSample
    GO
    
    USE WatchesDelSample
    
    -- Creating a reference table WatchType
    CREATE TABLE dbo.WatchType
    (
    	WatchTypeId INT IDENTITY(1,1),
    	Name VARCHAR(50)NOT NULL,
    	Detail VARCHAR(200)NULL 
    	CONSTRAINT PK_WatchType_WatchTypeId PRIMARY KEY (WatchTypeId)
    )
    GO
    
    -- Populating (adding rows to the) table WatchType
    SET IDENTITY_INSERT dbo.WatchType ON
    GO
    INSERT INTO dbo.WatchType
    (
      WatchTypeId
     ,Name
     ,Detail
    )
    VALUES
    (
      1  -- ID - INT Primary Key
     ,'Analogue' -- Name - varchar(50) NOT NULL
     ,'This is Analogue' -- Detail - varchar(200)
    ),
    (
      2  -- ID - INT Primary Key
     ,'Digital' -- Name - varchar(50) NOT NULL
     ,'This is Digital' -- Detail - varchar(200)
    ),
    (
      3  -- ID - INT Primary Key
     ,'Sports' -- Name - varchar(50) NOT NULL
     ,'This is Sports' -- Detail - varchar(200)
    );
    GO
    SET IDENTITY_INSERT dbo.WatchType OFF
    GO
    
    -- Creating a reference table Color
    CREATE TABLE dbo.Color
    (
    	ColorId INT IDENTITY(1,1),
    	Name VARCHAR(50)NOT NULL,
    	Detail VARCHAR(200)NULL 
    	CONSTRAINT PK_Color_ColorId PRIMARY KEY (ColorId)
    )
    GO
    
    -- Populating (adding rows to the) table Color
    SET IDENTITY_INSERT dbo.Color ON
    GO
    INSERT INTO dbo.Color
    (
      ColorId
     ,Name
     ,Detail
    )
    VALUES
    (
      1  -- ID - INT Primary Key
     ,'Black' -- Name - varchar(50) NOT NULL
     ,'This is Black' -- Detail - varchar(200)
    ),
    (
      2  -- ID - INT Primary Key
     ,'White' -- Name - varchar(50) NOT NULL
     ,'This is White' -- Detail - varchar(200)
    ),
    (
      3  -- ID - INT Primary Key
     ,'Blue' -- Name - varchar(50) NOT NULL
     ,'This is Blue' -- Detail - varchar(200)
    );
    GO
    SET IDENTITY_INSERT dbo.Color OFF
    GO
    
    -- Creating a table Watch
    CREATE TABLE dbo.Watch
    (
    	WatchId INT IDENTITY(1,1),
    	Name VARCHAR(50),
    	WatchTypeId INT,
    	ColorId INT,
    	Price DECIMAL(5,2),		
    	CONSTRAINT PK_Watch_WatchId PRIMARY KEY (WatchId)
    )
    GO
    
    -- Creating foreign key constraint on Watch table to get WatchTypeId values from WatchType table
    ALTER TABLE dbo.Watch
        ADD CONSTRAINT [FK_Watch_WatchType_WatchTypeId] 
    FOREIGN KEY ([WatchTypeId]) REFERENCES dbo.[WatchType] ([WatchTypeId]);
    
    -- Creating foreign key constraint on Watch table to get ColorId values from Color table
    ALTER TABLE dbo.Watch
        ADD CONSTRAINT [FK_Watch_Color_ColorId] 
    FOREIGN KEY ([ColorId]) REFERENCES dbo.[Color] ([ColorId]);
    
    
    -- Populating (adding rows to the) table Watch getting some columns values from reference tables
    SET IDENTITY_INSERT WatchesDelSample.dbo.Watch ON
    GO
    INSERT WatchesDelSample.dbo.Watch(WatchId, Name, WatchTypeId, ColorId, Price) VALUES (1, 'Casio', 1, 1, 100.00)
    INSERT WatchesDelSample.dbo.Watch(WatchId, Name, WatchTypeId, ColorId, Price) VALUES (2, 'Timex', 2, 2, 70.00)
    GO
    SET IDENTITY_INSERT WatchesDelSample.dbo.Watch OFF
    GO
    

    クイックデータチェック

    ウォッチのすべての行を表示してみましょう テーブル。そのためには、次のスクリプトを実行します。

    -- View the watch table data (rows)
    SELECT w.WatchId
          ,w.Name
          ,w.WatchTypeId
          ,w.ColorId
          ,w.Price FROM dbo.Watch w
    

    出力は次のとおりです。

    このデモでは、SQLServer用のdbForgeStudioを使用していることに注意してください。ただし、SQL Server Management Studio(SSMS)を使用して同じスクリプトを実行することはできます。結果は同じになります。

    タイプ列とカラー列の背後にあるID(コード)を理解する

    ご覧のとおり、ウォッチテーブルの次の列の下にいくつかのIDがあります。

    1. WatchTypeId
    2. ColorId

    これらの列は、最初に定義された参照テーブルから値を取得します。監視テーブルは、外部キー制約を介してこれらの参照テーブルに接続します。

    上記の出力で3つの問題が発生します:

    1. WatchTypeIdとColorIdは表示されますが、それらが何であるかはわかりません。
    2. これらのIDの意味を理解している場合は、常に元のテーブルに戻って確認する必要があります。
    3. 最も重要なのは、なぜ他のテーブルから色とタイプを取得する必要があるのですか?

    他のテーブルでColor(ColorId)とType(WatchTypeId)を定義したのには理由があります。これらの値が一貫していることを確認する必要があります。

    参照テーブルで元々値を定義していなかった場合は、色やタイプを表すために単語を混ぜることができたはずです。たとえば、両方のが存在する可能性があります およびブルース 、またはアナログ およびアナログ 。このような問題を回避するために、参照テーブルの色とタイプを標準化しています。次に、それらのコードをメインテーブルに渡します。

    Watchテーブルを他の参照テーブルと結合することで、これらのコードの背後にある値を取得できます。これはデータベース開発の一般的な方法です。

    IDの背後にあるタイプと色の値を使用してウォッチテーブルを表示する

    次のスクリプトを実行すると、色とタイプの背後にあるコードの実際の意味を確認できます。

    -- View the watch table data (rows)
    SELECT w.WatchId
          ,w.Name
          ,wt.Name AS WatchType
          ,c.Name AS ColorName
          ,w.Price FROM dbo.Watch w
      INNER JOIN dbo.Color c ON c.ColorId=w.ColorId
      INNER JOIN dbo.WatchType wt ON w.WatchTypeId = wt.WatchTypeId
    

    結果は次のとおりです。

    データベースアーキテクチャを理解する

    このデータベースのアーキテクチャに関する詳細情報が必要です。私たちの焦点は、テーブルが互いにどのようにリンクするかにあります。

    上の画像は、メインテーブルが一貫したデータを受信するのに役立つ参照テーブルのシナリオを示しています。多くのデータベースで一般的ですが、特に初心者にとっては単純なシナリオではありません。

    このようにリンクされている場合、上記のテーブルのいずれかから1つ以上の行を削除する方法を理解する必要があるため、このアーキテクチャを検討しています。

    参照(色)テーブルからの行の削除

    参照テーブルから行を削除できますか?答えを見つけましょう。

    Colorテーブルから最初の行を削除します:

    -- Deleting one row with color id 1 from the reference table color 
    DELETE FROM Color
    WHERE ColorId = 1
    

    結果は次のとおりです。

    このエラーは、必要な行を削除することが許可されていないことを意味します。

    つまり、別のテーブルによって参照されているテーブルから行を削除することはできません。

    リンクされた行とリンクされていない行

    参照テーブルの行を次の2つのカテゴリに分けてみましょう。

    1. リンクされた行。
    2. リンクされていない行。

    リンクされた行は、別のテーブルによって使用される参照テーブルの行です。リンクされていない行は、別のテーブルがアピールしない参照テーブルの行です。

    参照テーブルのリンクされていない行(レコード)をすぐに削除できます。

    ColorId(1)がメインのWatchテーブルを使用していたため、Colorテーブルから行を削除する以前の試みは失敗しました。

    参照テーブル(色)を表示

    参照テーブルを次のように表示します。

    -- View reference table Color
    SELECT c.ColorId
          ,c.Name
          ,c.Detail FROM dbo.Color c
    

    結果セットは以下のとおりです。

    前の出力から、テーブルに青の時計がまだ保存されていないため、色の青(ColorId:3)が時計テーブルで使用されていないことがわかります。

    参照(カラー)テーブルからリンクされていない行を削除する

    次のスクリプトを実行します。

    -- Deleting unlinked row with color id 3 from reference table Color
    DELETE FROM Color
    WHERE ColorId = 3 -- blue color
    

    行は正常に削除されました。表を表示して確認できます:

    --View reference table Color after deleting the unlinked row
    SELECT c.ColorId
          ,c.Name
          ,c.Detail FROM dbo.Color c
    

    結果セットは以下のとおりです。

    blueを含む行が表示されます 表から色が正常に削除されました。

    参照テーブルからのデータの削除に関するヒント

    別のテーブルまたはテーブルのグループを使用している場合、参照テーブルからレコード(行)を削除できないことに注意してください。ただし、使用されていない場合は、同じ(参照)テーブルからレコードを削除できます。

    参照(色)テーブルからリンクされた行を削除する

    色などの参照データを別のテーブルに渡すことを知っている参照テーブルから行を削除したい場合はどうなりますか?つまり、リンクされた行を参照テーブルから削除するにはどうすればよいですか?

    まず、その行が参照されているメインテーブルからその行を削除する必要があります。

    たとえば、の色を削除できます。 次のようにカラーテーブルから:

    1. メインテーブル(ウォッチ)から、色が白(IDに基づく)のすべての行を削除します。
    2. 色が白(idに基づく)である参照Colorテーブルから行を削除します。

    それでは、実際に調べてみましょう。

    メイン(ウォッチ)テーブルから色が白のすべての行を削除する

    私たちの目標は、の痕跡を取り除くことです 参照テーブルとメインテーブルの両方からの色。

    削除する前にデータを見てみましょう。メインテーブルの行数にカラーID2(白)が含まれていることを確認します:

    -- View Watch table before deleting rows with white color (color id:2)
     SELECT w.WatchId
           ,w.Name
           ,w.WatchTypeId
           ,w.ColorId
           ,w.Price FROM dbo.Watch w
      WHERE w.ColorId=2 -- White Color
    

    結果は以下のとおりです。

    次に、次のT-SQLスクリプトを実行して、カラーID2の行を削除します。

    -- Deleting all the rows with color id 2 from main table Watch
    DELETE FROM dbo.Watch
    WHERE ColorId = 2 -- white color 
    

    出力は次のとおりです。

    白い色のすべての行を削除した後、メインテーブルを表示します

    メインテーブルでカラーID2を含む行を確認する必要があります:

    -- View the watch table data (rows)
    SELECT w.WatchId
          ,w.Name
          ,wt.Name AS WatchType
          ,w.ColorId 
          ,c.Name AS ColorName
          ,w.Price FROM dbo.Watch w
      INNER JOIN dbo.Color c ON c.ColorId=w.ColorId
      INNER JOIN dbo.WatchType wt ON w.WatchTypeId = wt.WatchTypeId
    

    ご覧のとおり、白色の時計の記録はありません。これらの行がすべて正常に削除されたことを証明します。

    以前にリンクされた行を参照テーブルから削除する(色)

    メインテーブルから参照された行を削除した後、以前にリンクされた行を参照テーブルから削除することもできます。事実、そのリンクはもう存在しません。

    参照カラーテーブルに対して次のスクリプトを実行して、カラーID 2(白)の行を削除します。

    -- View reference table before removing color id 1 (white)
    SELECT c.ColorId
          ,c.Name
          ,c.Detail FROM dbo.Color c
    
    -- Deleting one row with color id 2 from the reference table color 
    DELETE FROM Color
    WHERE ColorId = 2 -- White Color
    
      -- View reference table after removing color id 1 (white)
    SELECT c.ColorId
          ,c.Name
          ,c.Detail FROM dbo.Color c
    

    出力は次のとおりです。

    おめでとうございます!

    参照テーブルから1つ以上の行を削除する方法を学びました。行が参照されている場合と参照されていない場合の両方で実行できます。また、メインテーブルから行を削除することも検討しました。

    すべてのデータを削除するためのヒント

    テーブルの切り捨てとして知られる別のT-SQLステートメントがあります –テーブルからすべてのデータを削除する方が効率的です。ただし、最初にメインテーブルからデータを削除する必要があるため、テーブルを他の場所で参照しないでください。これは、前にこの記事で示したものと同じです。次に、切り捨てを適用します 最終ステップとしての参照テーブルに対するステートメント。

    コードは次のとおりです。

    -- Deleting all rows from the main table using Truncate 
      TRUNCATE TABLE dbo.Watch
    

    ただし、Deleteステートメントの場合と同様に、切り捨てには十分注意する必要があります。 、またはテーブルからすべてのデータを削除することになります。

    アドバイスの言葉

    リアルタイムシナリオでの行の削除は、主に、メインデータベースから不要なデータ(廃止されたモデルなど)を削除するか、データをアーカイブしてアーカイブデータベースに保存するのに役立ちます。

    やるべきこと

    リンクされたテーブルなどの少し高度なシナリオで1つ以上の行を削除できるようになったので、スキルをさらに向上させるために次のことを試してください。

    1. 参照テーブルからアナログ時計の種類を削除します時計の種類 IDに基づいています。
    2. からすべての行を削除します 参照表。
    3. サンプルデータベースをリセットしてから、すべての(参照テーブルとメイン)テーブルからすべてのデータを削除できる速度を確認してください。

    1. MySQLをUbuntuにデプロイして完全に管理する方法

    2. エンベロープを取得します。つまり、重複する期間

    3. MySQLとMariaDBのレプリケーションフェイルオーバーを制御する方法

    4. エラー:Postgresを使用したシーケンスcitys_id_seqの権限が拒否されました