sql >> Database >  >> RDS >> Database

Aaneenschakeling in Transact-SQL

Inleiding

Ervan uitgaande dat u een tabel bijhoudt met klantgegevens en uw baas u vraagt ​​om hem de huidige lijst met klanten en hun telefoonnummers te sturen. Normaal gesproken extraheer je de gegevens en stuur je hem een ​​spreadsheet met rijen en kolommen. Je kunt er ook voor kiezen om een ​​beetje stijlvol te zijn en hem de benodigde informatie in een meer mensvriendelijk formaat te sturen. SQL Server biedt functies waarmee we dit kunnen bereiken door Engelse uitdrukkingen te combineren met gegevens in tabellen om een ​​uitvoer te presenteren die voor niet-technische mensen gemakkelijker te lezen is. Deze functies kunnen ook subtieler worden gebruikt.

De CONCAT-functie

De functie CONCAT accepteert twee of meer tekenreeksargumenten en retourneert de combinatie van dergelijke tekenreeksen als een enkele uitdrukking. Dit kan handig zijn als u de inhoud van verschillende kolommen als een enkele uitdrukking wilt weergeven. Een eenvoudig voorbeeld van het gebruik van deze functie wordt getoond in Listing 1.

-- Listing 1: Simple CONCAT Statement
select CONCAT('This','Function','joins','strings.') as statement1;
select CONCAT('This ','Function ','joins ','strings.') as statement2;
select CONCAT('This',' ','Function',' ','joins',' ','strings') as statement

Let op de variaties van deze verklaring met behulp van de spatie en de resultaten in Fig. 1.

Afb. 1. Eenvoudige CONCAT-verklaring

Als we de CONCAT-instructie proberen te gebruiken met een invoerwaarde van het gegevenstype INT, voert SQL Server een impliciete conversie uit en retourneert nog steeds een string-uitvoer zoals weergegeven in figuur 2. We kunnen bevestigen dat dit is wat er werkelijk gebeurt door diep in de details van de verklaring in Listing 2. Kijk eerst eens naar de structuur van de tabel waarin we geïnteresseerd zijn. Fig 2 laat ons zien dat het PhoneNumber# en FirstTranDate kolommen zijn respectievelijk BIGINT- en DATETIME-kolommen.

Afb. 2. Structuur van de klantentabel

-- Listing 2: Implicit Conversion When using CONCAT (BIGINT)
USE EXAM
GO
SELECT CONCAT(firstname
, ' '
,lastname
, '''s '
, 'Phone number is '
,phonenumber1) 
FROM CUSTOMER;

Een snelle blik op het uitvoeringsplan leert ons dat SQL Server een impliciete conversie uitvoert in de kolom Telefoonnummer1. Dit zal hetzelfde zijn als de kolom het datumgegevenstype was zoals weergegeven in Listing 4 en Fig. 4. De CONCAT-functie voert een impliciete conversie uit op basis van de regels die worden beschreven in de grafiek in Fig. 6.

Afb. 3. Impliciete conversie van BIGINT-gegevenstype naar VARCHAR

-- Listing 3: Implicit Conversion When using CONCAT (DATETIME)
USE EXAM
GO
SELECT FirstTranDate, CONCAT(FirstName
, ' '
,LastName
, '''s '
, 'first transaction date is '
,FirstTranDate) as STMT
FROM CUSTOMER;

Afb. 4. Impliciete conversie van DATETIME gegevenstype naar VARCHAR

Afb. 5. Impliciete conversie van BIGINT-gegevenstype naar VARCHAR

Afb. 6. Conversie van gegevenstype in SQL Server

De primaire use case voor deze functie kan worden afgeleid uit de bovenstaande demonstraties. Een voorbeeld is een geval waarin bepaalde informatie op een dashboard of webpagina in gebruiksvriendelijkere taal moet worden weergegeven met behulp van gegevens uit een aantal kolommen of zelfs afzonderlijke tabellen.

De CONCAT_WS-functie

De CONCAT_WS-functie is een uitbreiding van de CONCAT-functie. Hiermee kunnen we een gewenst scheidingsteken opgeven als de eerste parameter. Listing 4 toont ons een wijziging van een van de uitspraken die we eerder in Listing 1 gebruikten.

--Listing 4 Using CONCAT_WS
SELECT CONCAT('This',' ','Function',' ','joins',' ','strings') AS statement;
SELECT CONCAT('This',' ','Function',' ','joins',' ','strings') AS statement;
SELECT CONCAT_WS(' ','This','Function','joins','strings') AS statement;

Merk op dat CONCAT_WS het eenvoudiger maakt om een ​​statement te maken met een spatie als scheidingsteken in vergelijking met het invoeren van een spatie als argument na elk argument.

--Listing 5 Using CONCAT_WS with Columns
USE EXAM
GO
SELECT CONCAT(firstname
, ' '
,lastname
, '''s '
, 'Phone number is '
,phonenumber1) 
FROM CUSTOMER;


USE EXAM
GO
SELECT CONCAT_WS(' ',firstname
,lastname
, '''s '
, 'Phone number is'
,phonenumber1) 
FROM CUSTOMER;

Aaneenschakeling met het "+"-teken

SQL Server ondersteunt het gebruik van het "+"-teken om op een veel eenvoudigere manier te bereiken wat de CONCAT-functie doet. Deze benadering wordt meestal gebruikt om T-SQL-instructies te genereren wanneer u bewerkingen op een groot aantal objecten moet uitvoeren. Lijst 7 laat zien hoe we een statistische update-batch kunnen genereren voor alle tabellen in de examendatabase.

-- Listing 6 Generating Update Stats Statements
USE Exam
GO
SELECT 'UPDATE STATISTICS ' + name + ' WITH SAMPLE 25 PERCENT;' as STMT from sys.tables ;
SELECT 'UPDATE STATISTICS [' + name + '] WITH SAMPLE 25 PERCENT;' as STMT from sys.tables ;
GO

Let op de vierkante haken in de tweede verklaring. Het is handig bij het omgaan met een systeemobject met spaties of speciale tekens.

-- Listing 7 Generating Create User Statements
USE MASTER
GO
SELECT 'CREATE USER [' + LOGINNAME + '] FOR LOGIN [' + LOGINNAME + '] ;' 
AS STMT FROM SYSLOGINS
WHERE LOGINNAME NOT LIKE '#%';
GO
USE EXAM
GO
CREATE USER [sa] FOR LOGIN [sa] ;
CREATE USER [EPG-KIGIRI\ekocauris] FOR LOGIN [EPG-KIGIRI\ekocauris] ;
CREATE USER [KAIROSAFRIKA\kigiri] FOR LOGIN [KAIROSAFRIKA\kigiri] ;
CREATE USER [NT SERVICE\SQLWriter] FOR LOGIN [NT SERVICE\SQLWriter] ;
CREATE USER [NT SERVICE\Winmgmt] FOR LOGIN [NT SERVICE\Winmgmt] ;
CREATE USER [NT Service\MSSQL$I2019] FOR LOGIN [NT Service\MSSQL$I2019] ;
CREATE USER [NT AUTHORITY\SYSTEM] FOR LOGIN [NT AUTHORITY\SYSTEM] ;
CREATE USER [NT SERVICE\SQLAgent$I2019] FOR LOGIN [NT SERVICE\SQLAgent$I2019] ;
CREATE USER [NT SERVICE\SQLTELEMETRY$I2019] FOR LOGIN [NT SERVICE\SQLTELEMETRY$I2019] ;
CREATE USER [KAIROSAFRIKA\sberko] FOR LOGIN [KAIROSAFRIKA\sberko] ;
GO

Zodra de uitvoer is gegenereerd, kan deze worden gebruikt om gebruikers aan te maken in elke gewenste database, zoals weergegeven in Listing 7. Merk op dat we een filter hebben toegevoegd voor de inlognamen waarin we geïnteresseerd zijn. Deze aanpak kan worden gebruikt om allerlei soorten verklaringen te genereren en roepen dergelijke verklaringen binnen dezelfde sessie. Een complexer voorbeeld zijn de volgende instructies die op creatieve wijze alle indexen in elke database opnieuw opbouwen. (Zie Lijsten 8 en 9).

--Listing 8 Generating Index Rebuild Statements
USE EXAM
GO
CREATE TABLE #INDTAB (ID SMALLINT IDENTITY(1,1), REBUILDSTMT NVARCHAR(600))
INSERT INTO #INDTAB 
SELECT 'SET QUOTED_IDENTIFIER ON;
ALTER INDEX [' + B.NAME + '] 
ON [' + SCHEMA_NAME(C.SCHEMA_ID) + '].[' + OBJECT_NAME(A.OBJECT_ID) + '] 
REBUILD WITH (ONLINE = OFF
,FILLFACTOR=80
,SORT_IN_TEMPDB=ON
,PAD_INDEX = ON
, STATISTICS_NORECOMPUTE = OFF);'
--INTO #INDTAB
FROM SYS.DM_DB_INDEX_PHYSICAL_STATS (DB_ID(), NULL,
     NULL, NULL, NULL) AS A
    JOIN SYS.INDEXES AS B 
	JOIN SYS.OBJECTS AS C
ON B.OBJECT_ID = C.OBJECT_ID
ON A.OBJECT_ID = B.OBJECT_ID AND A.INDEX_ID = B.INDEX_ID WHERE AVG_FRAGMENTATION_IN_PERCENT > 30 ;
SELECT * FROM #INDTAB;
GO
DROP TABLE #INDTAB;
GO

--Listing 9 Generating and Executing Index Rebuild Statements
USE EXAM
GO
CREATE TABLE #INDTAB (ID SMALLINT IDENTITY(1,1), REBUILDSTMT NVARCHAR(600))
INSERT INTO #INDTAB 
SELECT 'SET QUOTED_IDENTIFIER ON;
ALTER INDEX [' + B.NAME + '] 
ON [' + SCHEMA_NAME(C.SCHEMA_ID) + '].[' + OBJECT_NAME(A.OBJECT_ID) + '] 
REBUILD WITH (ONLINE = OFF
,FILLFACTOR=80
,SORT_IN_TEMPDB=ON
,PAD_INDEX = ON
, STATISTICS_NORECOMPUTE = OFF);'
--INTO #INDTAB
FROM SYS.DM_DB_INDEX_PHYSICAL_STATS (DB_ID(), NULL,
     NULL, NULL, NULL) AS A
    JOIN SYS.INDEXES AS B 
	JOIN SYS.OBJECTS AS C
ON B.OBJECT_ID = C.OBJECT_ID
ON A.OBJECT_ID = B.OBJECT_ID AND A.INDEX_ID = B.INDEX_ID WHERE AVG_FRAGMENTATION_IN_PERCENT > 30 ;
GO
DECLARE @SQL NVARCHAR(4000);
SELECT @SQL= REBUILDSTMT FROM  #INDTAB ;
PRINT @SQL
EXEC SP_EXECUTESQL @SQL;
GO
DROP TABLE #INDTAB;
GO

De query in Listing 10 laat zien hoe we strings kunnen combineren met datums die expliciet zijn geconverteerd naar strings. De Aaneenschakeling van tekenreeksen wordt gebruikt om een ​​algemene back-uppadvariabele te genereren die later wordt gebruikt binnen de functie SP_MSFOREACHDB.

--Listing 10 Generating a Common Backup Path
EXEC SP_MSFOREACHDB @COMMAND1='
DECLARE @BACKUP SYSNAME
SET @BACKUP=N''G:\BACKUP\?''+CONVERT(NVARCHAR,GETDATE(),112)+N''.BAK''
USE [?]
IF      ''?''  NOT   IN ("MODEL","TEMPDB")
BEGIN
BACKUP DATABASE ? TO  DISK = @BACKUP WITH  INIT ,  NOUNLOAD ,  COMPRESSION,
NAME = N''?'',  NOSKIP , NOFORMAT
END'

Conclusie

In dit artikel hebben we een aantal manieren laten zien om aaneenschakeling in SQL Server te gebruiken. We hebben voorbeelden gegeven van de CONCAT-functie, de CONCAT_WS-functie en het gebruik van het “+”-teken. Alle drie de methoden kunnen erg handig zijn bij het genereren van uitspraken door waarden uit verschillende kolommen te combineren of om eenvoudig informatie weer te geven in een gewenst, mensvriendelijk formaat. Microsoft-documentatie bevat meer informatie over de syntaxis en mogelijkheden van deze functies.

Referenties

Casten en converteren (Transact-SQL)

Concat Transact-SQL

Concat_ws Transact-SQL

String aaneenschakeling


  1. Een lopende SELECT-instructie doden?

  2. Plsql om nummer (valuta) naar Italiaanse valuta te spellen zonder het vertalingsnummer hardgecodeerd te hebben

  3. Overdenkingen over SQL Server-beveiliging

  4. SQRT() Voorbeelden in SQL Server