Sök…


Anmärkningar

Detta är en uppsättning exempel som belyser grundläggande användning av SQL Server.

versioner

Version Utgivningsdatum
SQL Server 2016 2016/06/01
SQL Server 2014 2014/03/18
SQL Server 2012 2011-10-11
SQL Server 2008 R2 2010-04-01
SQL Server 2008 2008-08-06
SQL Server 2005 2005-11-01
SQL Server 2000 2000-11-01

INSERT / SELECT / UPDATE / DELETE: grunderna i Data Manipulation Language

D ata M anipulation L anguage (DML för kort) inkluderar operationer som INSERT , UPDATE och DELETE :

-- Create a table HelloWorld

CREATE TABLE HelloWorld (
    Id INT IDENTITY,
    Description VARCHAR(1000)
)


-- DML Operation INSERT, inserting a row into the table
INSERT INTO HelloWorld (Description) VALUES ('Hello World')


-- DML Operation SELECT, displaying the table 
SELECT * FROM HelloWorld  


-- Select a specific column from table
SELECT Description FROM HelloWorld


-- Display number of records in the table
SELECT Count(*) FROM HelloWorld


-- DML Operation UPDATE, updating a specific row in the table
UPDATE HelloWorld SET Description = 'Hello, World!' WHERE Id = 1


-- Selecting rows from the table (see how the Description has changed after the update?)
SELECT * FROM HelloWorld


-- DML Operation - DELETE, deleting a row from the table
DELETE FROM HelloWorld WHERE Id = 1


-- Selecting the table. See table content after DELETE operation 
SELECT * FROM HelloWorld

I det här skriptet skapar vi en tabell för att visa några grundläggande frågor.

Följande exempel visar hur du frågar tabeller:

USE Northwind;
GO
SELECT TOP 10 * FROM Customers 
ORDER BY CompanyName

kommer att välja de första 10 posterna i Customer , beställd av kolumnen CompanyName från databasen Northwind (som är en av Microsofts exempeldatabaser, den kan laddas ner här ):

Northwind databasfråga

Observera att Use Northwind; ändrar standarddatabasen för alla efterföljande frågor. Du kan fortfarande referera till databasen genom att använda den fullt kvalificerade syntaxen i form av [Databas]. [Schema]. [Tabell]:

SELECT TOP 10 * FROM Northwind.dbo.Customers 
ORDER BY CompanyName

SELECT TOP 10 * FROM Pubs.dbo.Authors
ORDER BY City

Detta är användbart om du frågar data från olika databaser. Observera att dbo , specificerat "emellan" kallas ett schema och måste specificeras när du använder den fullt kvalificerade syntaxen. Du kan tänka på det som en mapp i din databas. dbo är standardschemat. Standardschemat kan utelämnas. Alla andra användardefinierade scheman måste specificeras.

Om databastabellen innehåller kolumner som namnges som reserverade ord, t.ex. Date , måste du bifoga kolumnnamnet inom parentes, så här:

-- descending order
SELECT TOP 10 [Date] FROM dbo.MyLogTable
ORDER BY [Date] DESC

Detsamma gäller om kolumnnamnet innehåller mellanslag i dess namn (vilket inte rekommenderas). En alternativ syntax är att använda dubbla citat istället för fyrkantiga parenteser, t.ex.

-- descending order
SELECT top 10 "Date" from dbo.MyLogTable
order by "Date" desc 

är ekvivalent men inte så vanligt förekommande. Lägg märke till skillnaden mellan dubbla citat och enstaka citat: Enstaka citat används för strängar, dvs.

-- descending order
SELECT top 10 "Date" from dbo.MyLogTable
where UserId='johndoe'
order by "Date" desc 

är en giltig syntax. Observera att T-SQL har ett N prefix för NChar och NVarchar-datatyper, t.ex.

SELECT TOP 10 * FROM Northwind.dbo.Customers 
WHERE CompanyName LIKE N'AL%'
ORDER BY CompanyName

returnerar alla företag som har ett företagsnamn som börjar med AL ( % är ett vildkort, använd det som du skulle använda asterisken i en DOS-kommandorad, t.ex. DIR AL* ). För LIKE finns det ett par jokertecken tillgängliga. Titta här för att ta reda på mer information.

Fogar

Joins är användbara om du vill fråga fält som inte finns i en enda tabell, men i flera tabeller. Till exempel: Du vill fråga alla kolumner från Region tabellen i Northwind databasen. Men du märker att du också behöver RegionDescription , som lagras i en annan tabell, Region . Det finns emellertid en gemensam nyckel, RgionID som du kan använda för att kombinera denna information i en enda fråga enligt följande ( Top 5 returnerar bara de första fem raderna, uteslut den för att få alla rader):

SELECT TOP 5 Territories.*, 
    Regions.RegionDescription 
FROM Territories 
INNER JOIN Region 
    ON Territories.RegionID=Region.RegionID
ORDER BY TerritoryDescription

visar alla kolumner från Territories plus kolumnen RegionDescription från Region . Resultatet beställs av TerritoryDescription .

Tabell alias

När din fråga kräver en hänvisning till två eller flera tabeller, kan det vara bra att använda ett tabellalias. Tabellalias är korta referenser till tabeller som kan användas istället för ett fullständigt tabellnamn och kan minska skrivning och redigering. Syntaxen för att använda ett alias är:

<TableName> [as] <alias>

Var as är ett valfritt nyckelord. Till exempel kan den föregående frågan skrivas om som:

SELECT TOP 5 t.*, 
    r.RegionDescription 
FROM Territories t
INNER JOIN Region r 
    ON t.RegionID = r.RegionID
ORDER BY TerritoryDescription

Aliaser måste vara unika för alla tabeller i en fråga, även om du använder samma tabell två gånger. Till exempel, om din anställdstabell inkluderade ett SupervisorId-fält, kan du använda den här frågan för att returnera en anställd och hans handledares namn:

SELECT e.*, 
    s.Name as SupervisorName -- Rename the field for output
FROM Employee e
INNER JOIN Employee s
    ON e.SupervisorId = s.EmployeeId
WHERE e.EmployeeId = 111

fackföreningar

Som vi har sett tidigare lägger en Join till kolumner från olika tabellkällor. Men vad händer om du vill kombinera rader från olika källor? I det här fallet kan du använda en UNION. Anta att du planerar en fest och vill bjuda in inte bara anställda utan också kunderna. Då kan du köra den här frågan för att göra det:

SELECT FirstName+' '+LastName as ContactName, Address, City FROM Employees
UNION
SELECT ContactName, Address, City FROM Customers

Det kommer att returnera namn, adresser och städer från anställda och kunder i en enda tabell. Observera att dubbla rader (om det skulle finnas några) automatiskt elimineras (om du inte vill ha detta, använd en UNION ALL istället). Kolumnnummer, kolumnnamn, ordning och datatyp måste matcha alla utvalda uttalanden som ingår i facket - det är därför det första VÄLJET kombinerar FirstName och LastName från Employee till ContactName .

Tabellvariabler

Om du behöver ta itu med tillfälliga data (särskilt i en lagrad procedur) kan det vara användbart att använda tabellvariabler: Skillnaden mellan en "riktig" tabell och en tabellvariabel är att den bara finns i minnet för tillfällig behandling.

Exempel:

DECLARE @Region TABLE
(
  RegionID int, 
  RegionDescription NChar(50)
)

skapar en tabell i minnet. I det här fallet är prefixet @ obligatoriskt eftersom det är en variabel. Du kan utföra alla DML-operationer som nämns ovan för att infoga, radera och välja rader, t.ex.

INSERT INTO @Region values(3,'Northern')
INSERT INTO @Region values(4,'Southern')

Men normalt sett skulle du fylla i det baserat på ett riktigt bord som

INSERT INTO @Region
SELECT * FROM dbo.Region WHERE RegionID>2;

som skulle läsa de filtrerade värdena från den verkliga tabellen dbo.Region och infoga den i minnestabellen @Region - där den kan användas för vidare bearbetning. Till exempel kan du använda den i en koppling som

SELECT * FROM Territories t
JOIN @Region r on t.RegionID=r.RegionID

vilket i detta fall skulle återlämna alla Northern och Southern territorier. Mer detaljerad information finns här . Tillfälliga tabeller diskuteras här om du är intresserad av att läsa mer om det ämnet.

OBS! Microsoft rekommenderar endast användning av tabellvariabler om antalet rader med data i tabellvariabeln är mindre än 100. Om du arbetar med större mängder data, använd istället en temporär tabell eller temptabell.

SKRIVA UT

Visa ett meddelande till utgångskonsolen. Med hjälp av SQL Server Management Studio kommer detta att visas på meddelandefliken i stället för resultatfliken:

PRINT 'Hello World!';

VÄLJ alla rader och kolumner från en tabell

Syntax:

SELECT *
FROM table_name

Att använda asteriskoperatören * fungerar som en genväg för att välja alla kolumner i tabellen. Alla rader kommer också att väljas eftersom detta SELECT uttalande inte har en WHERE klausul för att ange filterkriterier.

Det här fungerar också på samma sätt om du lägger till ett alias i tabellen, till exempel e i detta fall:

SELECT *
FROM Employees AS e

Eller om du ville välja allt från en specifik tabell kan du använda alias + ". *":

SELECT e.*, d.DepartmentName
FROM Employees AS e
    INNER JOIN Department AS d 
        ON e.DepartmentID = d.DepartmentID

Databasobjekt kan också nås med helt kvalificerade namn:

SELECT * FROM [server_name].[database_name].[schema_name].[table_name]

Detta rekommenderas inte nödvändigtvis, eftersom ändring av server- och / eller databasnamn skulle leda till att frågorna med helt kvalificerade namn inte längre körs på grund av ogiltiga objektnamn.

Observera att fälten före table_name kan utelämnas i många fall om frågorna körs på en respektive server, databas och schema. Det är dock vanligt att en databas har flera scheman, och i dessa fall ska schemanamnet inte utelämnas när det är möjligt.

Varning: Att använda SELECT * i produktionskod eller lagrade procedurer kan leda till problem senare (eftersom nya kolumner läggs till i tabellen, eller om kolumner är omordnade i tabellen), särskilt om din kod gör enkla antaganden om kolumnernas ordning, eller antal kolumner som returnerats. Så det är säkrare att alltid uttryckligen ange kolumnnamn i SELECT-satser för produktionskod.

SELECT col1, col2, col3
FROM table_name

Välj rader som matchar ett villkor

I allmänhet är syntaxen:

SELECT <column names>
FROM <table name>
WHERE <condition>

Till exempel:

SELECT FirstName, Age
FROM Users
WHERE LastName = 'Smith'

Förhållandena kan vara komplexa:

SELECT FirstName, Age
FROM Users
WHERE LastName = 'Smith' AND (City = 'New York' OR City = 'Los Angeles')

UPDATE Specific Rad

UPDATE HelloWorlds
SET HelloWorld = 'HELLO WORLD!!!'
WHERE Id = 5

Ovanstående kod uppdaterar värdet på fältet "HelloWorld" med "HELLO WORLD !!!" för posten där "Id = 5" i HelloWorlds-tabellen.

Obs: I ett uppdateringsförklaring rekommenderas att du använder en "var" -klausul för att undvika uppdatering av hela tabellen såvida inte och tills ditt krav är annorlunda.

UPPDATERA Alla rader

En enkel form för uppdatering ökar alla värden i ett givet fält i tabellen. För att kunna göra det måste vi definiera fältet och inkrementvärdet

Följande är ett exempel som ökar Score med 1 (i alla rader):

UPDATE Scores
SET score = score + 1  

Det kan vara farligt eftersom du kan förstöra dina data om du av misstag gör en UPDATE för en specifik rad med en UPDATE för alla rader i tabellen.

Kommentarer i kod

Transact-SQL stöder två former av kommentarskrivning. Kommentarer ignoreras av databasmotorn och är avsedda för människor att läsa.

Kommentarer föregås av -- och ignoreras tills en ny rad möts:

-- This is a comment
SELECT *
FROM MyTable -- This is another comment
WHERE Id = 1;

Slash-stjärnkommentarer börjar med /* och slutar med */ . All text mellan dessa avgränsare betraktas som ett kommentarblock.

/* This is
a multi-line
comment block. */
SELECT Id = 1, [Message] = 'First row'
UNION ALL
SELECT 2, 'Second row'
/* This is a one liner */
SELECT 'More';

Slash-stjärnkommentarer har fördelen att hålla kommentaren användbar om SQL-uttalandet förlorar nya radtecken. Detta kan hända när SQL fångas under felsökning.

Slash star-kommentarer kan kapslas och en start /* inuti en slash star-kommentar måste avslutas med en */ att vara giltig. Följande kod resulterar i ett fel

/*
SELECT *
FROM CommentTable
WHERE Comment = '/*'
*/

Slashstjärnan trots att inne i offerten betraktas som början på en kommentar. Därför måste det avslutas med ytterligare ett slutstjärna. Rätt sätt skulle vara

/*
SELECT *
FROM CommentTable
WHERE Comment = '/*'
*/  */

Hämta grundläggande serverinformation

SELECT @@VERSION

Returnerar versionen av MS SQL Server som körs på instansen.

SELECT @@SERVERNAME

Returnerar namnet på MS SQL Server-instansen.

SELECT @@SERVICENAME

Returnerar namnet på Windows-tjänsten MS SQL Server körs som.

SELECT serverproperty('ComputerNamePhysicalNetBIOS');

Returnerar det fysiska namnet på maskinen där SQL Server körs. Användbart för att identifiera noden i ett failover-kluster.

SELECT * FROM fn_virtualservernodes();

I ett failover-kluster returnerar varje nod där SQL Server kan köras. Det ger ingenting om inte ett kluster.

Använda transaktioner för att ändra data säkert

När du ändrar data i ett DML-kommando (Data Manipulation Language) kan du ta bort dina ändringar i en transaktion. DML inkluderar UPDATE , TRUNCATE , INSERT och DELETE . Ett av sätten att du kan se till att du ändrar rätt data skulle vara att använda en transaktion.

DML-ändringar tar ett lås på de berörda raderna. När du påbörjar en transaktion måste du avsluta transaktionen eller alla objekt som ändras i DML kommer att förbli låsta av den som började transaktionen. Du kan avsluta din transaktion med antingen ROLLBACK eller COMMIT . ROLLBACK returnerar allt inom transaktionen till sitt ursprungliga tillstånd. COMMIT placerar data i ett slutligt tillstånd där du inte kan ångra dina ändringar utan ytterligare ett DML-uttalande.

Exempel:

--Create a test table

USE [your database]
GO
CREATE TABLE test_transaction (column_1 varchar(10))
GO

INSERT INTO 
 dbo.test_transaction
        ( column_1 )
VALUES
        ( 'a' )

BEGIN TRANSACTION --This is the beginning of your transaction

UPDATE dbo.test_transaction
SET column_1 = 'B'
OUTPUT INSERTED.*
WHERE column_1 = 'A'
  

ROLLBACK TRANSACTION  --Rollback will undo your changes
           --Alternatively, use COMMIT to save your results

SELECT * FROM dbo.test_transaction   --View the table after your changes have been run

DROP TABLE dbo.test_transaction

Anmärkningar:

  • Detta är ett förenklat exempel som inte inkluderar felhantering. Men varje databasoperation kan misslyckas och därmed kasta ett undantag. Här är ett exempel på hur en sådan felhantering kan se ut. Du bör aldrig använda transaktioner utan en felhanterare , annars kan du lämna transaktionen i okänt tillstånd.
  • Beroende på isoleringsnivå sätter transaktioner lås på den information som fråges eller ändras. Du måste se till att transaktioner inte körs under en lång tid, eftersom de låser poster i en databas och kan leda till dödlås med andra parallella löpande transaktioner. Håll operationerna inkapslade i transaktioner så korta som möjligt och minimera effekten med mängden data du låser.

RADERA Alla rader

DELETE
FROM Helloworlds

Detta raderar alla data från tabellen. Tabellen innehåller inga rader efter att du har kört den här koden. Till skillnad från DROP TABLE , detta bevarar själva tabellen och dess struktur och du kan fortsätta att infoga nya rader i det bordet.

Ett annat sätt att ta bort alla rader i tabellen är att avkorta det på följande sätt:

TRUNCATE TABLE HelloWords

Skillnaden med DELETE-operation är flera:

  1. Trunkering fungerar inte i transaktionsloggfilen
  2. Om existerande IDENTITY fält återställs detta
  3. TRUNCATE kan tillämpas på hela tabellen och ingen på en del av det (istället med DELETE kommando kan du associera en WHERE klausul)

Begränsningar av TRUNCATE

  1. Kan inte TRUNCATE en tabell om det finns en FOREIGN KEY
  2. Om tabellen deltar i en INDEXED VIEW
  3. Om tabellen publiceras med TRANSACTIONAL REPLICATION eller MERGE REPLICATION
  4. Det avfyrar ingen TRIGGER som definieras i tabellen

[sic]

TRUNKATBORD

TRUNCATE TABLE Helloworlds 

Den här koden raderar all data från tabellen Helloworlds. Trunkeringstabellen är nästan lik Delete from Table . Skillnaden är att du inte kan använda där klausuler med Trunkera. Trunkeringstabellen anses vara bättre än ta bort eftersom den använder mindre transaktionsloggplatser.

Observera att om en identitetskolumn finns, återställs den till det ursprungliga utsädesvärdet (till exempel startas automatiskt inkrementerat ID från 1). Detta kan leda till inkonsekvens om identitetskolumnerna används som en främmande nyckel i en annan tabell.

Skapa en ny tabell och infoga poster från den gamla tabellen

SELECT * INTO NewTable FROM OldTable

Skapar ett nytt bord med strukturen i det gamla bordet och sätter in alla rader i det nya bordet.

Vissa begränsningar

  1. Du kan inte ange en tabellvariabel eller en tabellvärderad parameter som den nya tabellen.
  2. Du kan inte använda SELECT ... INTO för att skapa en partitionerad tabell, även när källtabellen är partitionerad. VÄLJ ... INTO använder inte partitionsschemat i källtabellen; istället skapas den nya tabellen i standardfilgruppen. För att infoga rader i en partitionerad tabell måste du först skapa den partitionerade tabellen och sedan använda INSERT INTO ... SELECT FROM-satsen.
  3. Index, begränsningar och triggers som definieras i källtabellen överförs inte till den nya tabellen, och de kan inte heller specificeras i SELECT ... INTO-uttalandet. Om dessa objekt krävs, kan du skapa dem efter att SELECT ... INTO har utförts.
  4. Att ange en ORDER BY-klausul garanterar inte att raderna infogas i den angivna ordningen. När en gles kolumn ingår i väljlistan överförs inte den glesa kolumnegenskapen till kolumnen i den nya tabellen. Om den här egenskapen krävs i den nya tabellen, ändra kolumndefinitionen efter att SELECT ... INTO har uttalat för att inkludera den här egenskapen.
  5. När en beräknad kolumn ingår i väljlistan är motsvarande kolumn i den nya tabellen inte en beräknad kolumn. Värdena i den nya kolumnen är de värden som beräknades vid tidpunkten SELECT ... INTO kördes.

[ sic ]

Få tabellrad

Följande exempel kan användas för att hitta det totala antal rader för en specifik tabell i en databas om table_name ersätts av tabellen du vill fråga:

SELECT COUNT(*) AS [TotalRowCount] FROM table_name;

Det är också möjligt att få radräkningen för alla tabeller genom att gå tillbaka till tabellens partition baserat på tabellernas HEAP (index_id = 0) eller klusterklusterindex (index_id = 1) med följande skript:

SELECT  [Tables].name                AS [TableName],
        SUM( [Partitions].[rows] )    AS [TotalRowCount]
FROM    sys.tables AS [Tables]
JOIN    sys.partitions AS [Partitions]
    ON  [Tables].[object_id]    =    [Partitions].[object_id]
    AND [Partitions].index_id IN ( 0, 1 )
--WHERE    [Tables].name = N'table name' /* uncomment to look for a specific table */
GROUP BY    [Tables].name;

Detta är möjligt eftersom varje tabell i huvudsak är en enda partitionstabell, såvida inte extra partitioner läggs till den. Det här skriptet har också fördelen att inte störa läs / skrivoperationer i tabellraderna.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow