sql >> Databáze >  >> RDS >> Sqlserver

SQL Server DELETE – odstranění jednoho nebo více řádků z tabulky s mírně pokročilými scénáři

Aktuální článek se zaměřuje na mírně pokročilé použití příkazu DELETE k odstranění jednoho nebo více záznamů (řádků) z tabulky. I když se zaměřuje převážně na začátečníky, jeho tipy mohou pomoci všem databázovým specialistům.

Předpoklady:Základní scénáře příkazu DELETE

Pokud ještě neznáte základní použití příkazu Delete, doporučujeme vám přečíst si předchozí článek SQL Server DELETE – Odstranění jednoho nebo více řádků z tabulky. Tento článek se zaměřuje na následující aspekty:

  1. Nastavení vzorové databáze.
  2. Spouštění skriptů SQL proti ukázkové databázi.
  3. Vytvoření tabulky ve vzorové databázi a vložení dat do ní.
  4. Smazání všech řádků z tabulky.
  5. Odstranění jednoho nebo více řádků z tabulky na základě podmínky.
  6. Odstranění jednoho nebo více řádků z tabulky na základě více podmínek.

Tato data je zásadní pochopit, než přejdeme k mírně pokročilému použití příkazu Delete, takže pokud zatím nemáte potřebné znalosti, přečtěte si tento článek.

Mírně pokročilé scénáře pro příkaz DELETE

Stejně jako u každého jiného návodu musíme nejprve nastavit vzorovou databázi, abychom s ní mohli bezpečně otestovat spouštění našich skriptů.

Tip k nastavení ukázkové databáze

Vřele doporučuji nejprve nainstalovat SQL Server Developer Edition na váš počítač lokálně. Je to lepší pro účely učení a testování.

SQL Server Developer Edition ke stažení

Nastavení ukázkové databáze (WatchesDelSample)

Chystáme se vytvořit databázi s názvem WatchesDelSample. Tato databáze obsahuje následující tři tabulky:

  1. Sledujte.
  2. Barva.
  3. Typ hodinek.

Stolek Watch je hlavní. Obsahuje název, barvu a typ hodinek. Informace o typu a barvě pocházejí ze dvou referenčních tabulek Barva a WatchType připojeno pomocí cizích klíčů.

Nastavte ukázkovou databázi pomocí následujícího skriptu:

-- 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

Rychlá kontrola dat

Podívejme se na všechny řádky Hodinky stůl. Za tímto účelem spusťte následující skript:

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

Výstup je následující:

Všimněte si, že pro tuto ukázku používám dbForge Studio pro SQL Server. Pro spouštění stejných skriptů však můžete použít SQL Server Management Studio (SSMS) – výsledky budou stejné.

Porozumění ID (kódům) za sloupci Typ a Barva

Jak můžete vidět, v následujících sloupcích tabulky Watch jsou některá ID:

  1. WatchTypeId
  2. ColorId

Tyto sloupce získávají hodnoty z referenčních tabulek, kde byly původně definovány. Tabulka Watch se k těmto referenčním tabulkám připojuje prostřednictvím omezení cizího klíče.

S výše uvedeným výstupem dochází ke třem problémům:

  1. Vidíme WatchTypeId a ColorId, ale nerozumíme tomu, co to je.
  2. Pokud rozumíme tomu, co tato ID znamenají, musíme se neustále vracet k jejich původním tabulkám a kontrolovat.
  3. Co je nejdůležitější, proč potřebujeme získávat barvu a typ z jiných tabulek?

Existuje důvod, proč jsme barvu (ColorId) a typ (WatchTypeId) definovali v jiných tabulkách. Musíme zajistit, aby tyto hodnoty zůstaly konzistentní.

Pokud jsme původně nedefinovali hodnotu v referenčních tabulkách, mohli jsme smíchat slova, aby reprezentovala barvu nebo typ. Například mohou být obě modré a Blues nebo Analogové a Analogové . Abychom se tomuto problému vyhnuli, standardizujeme barvy a typy v referenčních tabulkách. Poté předáme jejich kódy hlavnímu stolu.

Spojením tabulky Watch s jinými referenčními tabulkami můžeme získat hodnoty za těmito kódy. Je to běžná praxe při vývoji databází.

Zobrazení tabulky sledování s hodnotami typu a barvy za ID

Skutečný význam kódů za barvou a typem můžeme zobrazit spuštěním následujícího skriptu:

-- 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

Výsledek je následující:

Porozumění architektuře databáze

Potřebujeme více informací o architektuře této databáze. Zaměřujeme se na to, jak jsou tabulky vzájemně propojeny.

Výše uvedený obrázek ukazuje scénář referenčních tabulek, které pomáhají hlavní tabulce přijímat konzistentní data. Není to jednoduchý scénář zejména pro začátečníky, i když je v mnoha databázích běžný.

Studujeme tuto architekturu, protože potřebujeme pochopit, jak odstranit jeden nebo více řádků z kterékoli z výše uvedených tabulek, když jsou takto propojeny.

Odstranění řádku z referenční (Barvy) tabulky

Můžeme odstranit řádek z referenční tabulky nebo ne? Pojďme zjistit odpověď.

Smažeme první řádek z tabulky barev:

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

Výsledek je následující:

Chyba znamená, že není povoleno odstranit požadovaný řádek.

Jinými slovy, nemůžeme odstranit řádek z tabulky, na který odkazuje jiná tabulka.

Propojené řádky vs. nepropojené řádky

Rozdělme řádky referenční tabulky do následujících dvou kategorií:

  1. Propojené řádky.
  2. Odpojené řádky.

Propojený řádek je řádek referenční tabulky, který používá jiná tabulka. Nepropojený řádek je řádek referenční tabulky, na který se jiná tabulka nevztahuje.

Nepropojené řádky (záznamy) referenční tabulky můžeme rovnou smazat.

Náš dřívější pokus o odstranění řádku z tabulky barev selhal, protože toto ColorId (1) bylo používáno v hlavní tabulce Watch.

Zobrazit referenční tabulku (barva)

Podívejme se na referenční tabulku následovně:

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

Sada výsledků je níže:

Z předchozích výstupů víme, že modrá barva (ColorId:3) není v tabulce Watch používána, protože v tabulce zatím nejsou uloženy žádné modré hodinky.

Odstranění nepropojeného řádku z referenční tabulky (Barva)

Spusťte následující skript:

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

Řádek jsme úspěšně smazali a můžeme to potvrdit zobrazením tabulky:

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

Sada výsledků je níže:

Ukazuje, že řádek obsahující modrou barva byla úspěšně odstraněna z tabulky.

Tip ohledně odstranění dat z referenční tabulky

Pamatujte, že nemůžete odstranit záznam (řádek) z referenční tabulky, pokud je používán jinou tabulkou nebo skupinou tabulek. Můžete však odstranit záznam ze stejné (referenční) tabulky, pokud se nepoužívá.

Odstranění propojeného řádku z referenční (Barvy) tabulky

Co když chceme odstranit řádek z referenční tabulky s vědomím, že předává referenční data, jako jsou barvy, do jiné tabulky? Jinými slovy, jak odstraníme propojený řádek z referenční tabulky?

Nejprve musíme odstranit tento řádek z hlavní tabulky, kde se na něj odkazuje.

Můžeme například smazat barvu Bílou z tabulky barev následovně:

  1. Smažte všechny řádky z hlavní tabulky (Watch), kde je barva bílá (na základě id).
  2. Smažte řádek z referenční tabulky barev, kde je barva bílá (na základě id).

Nyní to prozkoumáme v praxi.

Odstranění všech řádků, kde je barva bílá, z hlavní (sledovací) tabulky

Naším cílem je odstranit stopy bílého barva z referenční i hlavní tabulky.

Podívejme se na data, než je smažeme. Chceme zkontrolovat, kolik řádků z hlavní tabulky obsahuje id barvy 2 (bílá):

-- 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

Výsledek je níže:

Nyní odstraňte řádky s ID barvy 2 spuštěním následujícího skriptu T-SQL:

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

Výstup je následující:

Zobrazte hlavní tabulku po odstranění všech řádků s bílou barvou

Musíme v hlavní tabulce zkontrolovat všechny řádky obsahující ID barvy 2:

-- 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

Jak vidíme, záznamy pro bílé hodinky chybí. Dokazuje to, že jsme úspěšně smazali všechny tyto řádky.

Odstranění dříve propojeného řádku z referenční tabulky (barva)

Poté, co odstraníme odkazované řádky z hlavní tabulky, můžeme také odstranit dříve propojený řádek z referenční tabulky. Faktem je, že tento odkaz už tam není.

Spusťte následující skript proti referenční tabulce barev a odstraňte řádek s ID barvy 2 (bílá):

-- 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

Výstup je následující:

Gratulujeme!

Naučili jsme se, jak odstranit jeden nebo více řádků z referenční tabulky. Můžeme to udělat, pokud se na řádek odkazuje, i pokud ne. Také jsme prozkoumali mazání řádků z hlavní tabulky.

Tip ohledně smazání všech dat

Existuje další příkaz T-SQL známý jako Truncate Table – je efektivnější pro odstranění všech dat z tabulky. Na tabulku se však nesmí odkazovat jinde, protože pak musíte nejprve odstranit data z hlavní tabulky. Je to stejné, jak jsme si ukázali v tomto článku dříve. Poté použijeme Zkrácení prohlášení oproti referenční tabulce jako poslední krok.

Kód je následující:

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

Stejně jako u příkazu Delete však musíte být velmi opatrní u Truncate nebo nakonec smažete všechna data z tabulky.

Slovo doporučení

Mazání řádků ve scénářích v reálném čase nám většinou pomáhá buď odstranit nežádoucí data (jako jsou vyřazené modely) z hlavní databáze, nebo data archivovat a uložit je do archivní databáze.

Co dělat

Nyní, když můžete odstranit jeden nebo více řádků v mírně pokročilých scénářích, jako jsou propojené tabulky, vyzkoušejte následující věci, abyste své dovednosti dále zlepšili:

  1. Odstraňte analogový typ hodinek z referenční tabulky WatchType na základě ID.
  2. Smažte všechny řádky z Barvy referenční tabulka.
  3. Zkuste resetovat ukázkovou databázi a pak uvidíte, jak rychle můžete odstranit všechna data ze všech (referenčních a hlavních) tabulek.

  1. Chyby T-SQL, úskalí a osvědčené postupy – funkce oken

  2. Jak importovat výpis Heroku PG do místního počítače

  3. Oracle SQL dotaz:Získejte nejnovější hodnoty pro skupinu na základě času

  4. Vložte časové razítko do databáze pomocí ContentValues