Wprowadzenie
Zakładając, że prowadzisz tabelę zawierającą dane klientów, a Twój szef prosi Cię o przesłanie mu aktualnej listy klientów i ich numerów telefonów. Zazwyczaj wyodrębniasz dane i wysyłasz mu arkusz kalkulacyjny z wierszami i kolumnami. Możesz również zdecydować się na odrobinę szyku i wysłać mu wymagane informacje w bardziej przyjaznym dla ludzi formacie. SQL Server udostępnia funkcje, które pozwalają nam to osiągnąć, łącząc wyrażenia angielskie z danymi w tabelach w celu przedstawienia danych wyjściowych, które są łatwiejsze do odczytania dla osób nie posiadających wiedzy technicznej. Funkcje te można również wykorzystać do bardziej subtelnych zastosowań.
Funkcja CONCAT
Funkcja CONCAT akceptuje dwa lub więcej argumentów ciągu i zwraca kombinację takich ciągów jako pojedyncze wyrażenie. Może to być przydatne, jeśli chcesz wyświetlić zawartość różnych kolumn jako pojedyncze wyrażenie. Prosty przykład użycia tej funkcji pokazano na Listingu 1.
-- Listing 1:Prosta instrukcja CONCATselect CONCAT('This','Function','joins','strings.') as statement1;select CONCAT('This ','Funkcja ','joins ','strings .') jako statement2;wybierz CONCAT('This',' ','Function',' ','joins',' ' ','strings')' jako statement
Zwróć uwagę na różnice w tym stwierdzeniu za pomocą spacji i wyników na ryc. 1.
Rys. 1. Proste oświadczenie CONCAT
Jeśli spróbujemy użyć wyrażenia CONCAT z wartością wejściową typu danych INT, SQL Server wykona niejawną konwersję i nadal zwraca wynik w postaci ciągu, jak pokazano na rys. 2. Możemy potwierdzić, że tak się dzieje, zagłębiając się głęboko w szczegóły instrukcji z Listingu 2. Przede wszystkim spójrz na strukturę interesującej nas tabeli. Rys. 2 pokazuje, że PhoneNumber# i Data Pierwszego Przekazania kolumny to odpowiednio kolumny BIGINT i DATETIME.
Rys. 2. Struktura tabeli klientów
-- Listing 2:Niejawna konwersja podczas używania CONCAT (BIGINT)USE EXAMGOSELECT CONCAT(imię, ' ',nazwisko, '''s ', 'Numer telefonu to ',numer telefonu1) FROM CUSTOMER;
Szybkie spojrzenie na plan wykonania pokazuje, że SQL Server wykonuje niejawną konwersję w kolumnie PhoneNumber1. Będzie tak samo, jeśli kolumna była typem danych daty, jak pokazano na Listingu 4 i Rys. 4. Funkcja CONCAT wykonuje niejawną konwersję na podstawie reguł przedstawionych na wykresie pokazanym na rys. 6.
Rys. 3. Niejawna konwersja typu danych BIGINT na VARCHAR
-- Listing 3:Konwersja niejawna Podczas używania CONCAT (DATETIME)USE EXAMGOSELECT FirstTranDate, CONCAT(FirstName, ' ',LastName, '''s ', 'pierwsza data transakcji to ', FirstTranDate) jako STMTFROM CUSTOMER;
Rys. 4. Niejawna konwersja DATETIME typ danych na VARCHAR
Rys. 5. Niejawna konwersja typu danych BIGINT na VARCHAR
Rys. 6. Konwersja typu danych w SQL Server
Podstawowy przypadek użycia tej funkcji można wywnioskować z powyższych demonstracji. Przykładem może być przypadek, w którym niektóre informacje muszą być wyświetlane na pulpicie nawigacyjnym lub stronie internetowej w bardziej przyjaznym języku, przy użyciu danych z wielu kolumn lub nawet oddzielnych tabel.
Funkcja CONCAT_WS
Funkcja CONCAT_WS jest rozszerzeniem funkcji CONCAT. Pozwala nam określić żądany separator jako pierwszy parametr. Listing 4 pokazuje nam modyfikację jednego z wyrażeń, których użyliśmy wcześniej na Listingu 1.
--Listing 4 Używanie CONCAT_WSSELECT CONCAT('This',' ','Funkcja',' ','joins',' ','strings') Instrukcja AS;SELECT CONCAT('This',' ',' Funkcja”, „”, „połączenia”, „”, „ciągi”) Instrukcja AS;SELECT CONCAT_WS(„”, „To”, „Funkcja”, „połączenia”, „ciągi”) Instrukcja AS;
Zauważ, że CONCAT_WS ułatwia konstruowanie instrukcji ze spacją jako separatorem w porównaniu z wprowadzaniem spacji jako argumentu po każdym argumencie.
--Listing 5 Używanie CONCAT_WS z kolumnamiUSE EXAMGOSELECT CONCAT(imię, ' ',nazwisko, '''s ', 'Numer telefonu to ',numer telefonu1) FROM CUSTOMER;USE EXAMGOSELECT CONCAT_WS(' ',imię,nazwisko, ' ''', 'Numer telefonu to',numer telefonu1) OD KLIENTA;
Połączenie ze znakiem „+”
SQL Server obsługuje użycie znaku „+”, aby osiągnąć to, co robi funkcja CONCAT w znacznie prostszy sposób. Takie podejście jest zwykle używane do generowania instrukcji T-SQL, gdy trzeba wykonać operacje na dużej liczbie obiektów. Listing 7 pokazuje, jak możemy wygenerować partię aktualizacji statystyk dla wszystkich tabel w bazie danych egzaminów.
-- Listing 6 Generowanie zestawień statystyk aktualizacjiUSE ExamGOSELECT 'UPDATE STATISTICS ' + nazwa + ' WITH SAMPLE 25 PROCENT;' jako STMT z sys.tables;SELECT 'UPDATE STATISTICS [' + name + '] WITH SAMPLE 25 PROCENT;' jako STMT z sys.tables;GO
Zwróć uwagę na nawiasy kwadratowe w drugiej instrukcji. Jest to przydatne, gdy mamy do czynienia z obiektem systemowym ze spacjami lub znakami specjalnymi.
-- Listing 7 Generowanie tworzenia instrukcji użytkownikaUSE MASTERGOSELECT 'CREATE USER [' + LOGINNAME + '] FOR LOGIN [' + LOGINNAME + '];' AS STMT Z SYSLOGINSWHERE LOGINNAME NIE PODOBNY '#%';GOUSE EXAMGOCREATE USER [sa] DO ZALOGOWANIA [sa];CREATE USER [EPG-KIGIRI\ekocauris] DO LOGOWANIA [EPG-KIGIRI\ekocauris];CREATE USER\KAIROS 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
Po wygenerowaniu danych wyjściowych można je wykorzystać do tworzenia użytkowników w dowolnej pożądanej bazie danych, jak pokazano na Listingu 7. Zauważ, że dodaliśmy filtr dla interesujących nas nazw logowania. To podejście może służyć do generowania wszelkiego rodzaju zestawień i wywoływać takie oświadczenia w ramach tej samej sesji. Bardziej złożonym przykładem są poniższe instrukcje, które twórczo odbudowują wszystkie indeksy w dowolnej bazie danych. (Patrz wykazy 8 i 9).
--Listing 8 Generowanie instrukcji odbudowy indeksuUSE EXAMGOCREATE 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 #INDTABFROM SYS.DM_DB_INDEX_PHYSICAL_STATS (DB_ID(), NULL, NULL, NULL, NULL) JAKO JOIN SYS.INDEXES JAK B JOIN SYS.OBJECTS JAK CON B.OBJECT_ID =C.OBJECT_IDON A.OBJECT_ID =B .OBJECT_ID AND A.INDEX_ID =B.INDEX_ID WHERE AVG_FRAGMENTATION_IN_PERCENT> 30;SELECT * FROM #INDTAB;GODROP TABLE #INDTAB;GO--Listing 9 Generowanie i wykonywanie instrukcji odbudowy indeksuUSE EXAMGOCREATE TABLE #INDTABENTITY(ID SMALLINT) , 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 #INDTABFROM SYS.DM_DB_INDEX_PHYSICAL_STATS (DB_ID(), NULL, NULL, NULL ) JAKO JOIN SYS.INDEXES AS B JOIN SYS.OBJECTS AS CON B.OBJECT_ID =C.OBJECT_IDON A.OBJECT_ID =B.OBJECT_ID AND A.INDEX_ID =B.INDEX_ID WHERE AVG_FRAGMENTATION_IN_PERCENT> 30;GODECLARE(4000 NVAR); SELECT @SQL=REBUILDSTMT FROM #INDTAB;PRINT @SQLEXEC SP_EXECUTESQL @SQL;GODROP TABLE #INDTAB;GO
Zapytanie z listingu 10 pokazuje, jak możemy połączyć ciągi z datami jawnie przekonwertowanymi na ciągi. Konkatenacja ciągów służy do generowania wspólnej zmiennej ścieżki kopii zapasowej, która jest później używana w funkcji SP_MSFOREACHDB.
Wniosek
W tym artykule pokazaliśmy kilka sposobów wykorzystania konkatenacji w SQL Server. Podaliśmy przykłady funkcji CONCAT, funkcji CONCAT_WS oraz użycia znaku „+”. Wszystkie trzy metody mogą być bardzo przydatne w generowaniu zestawień poprzez łączenie wartości z różnych kolumn lub po prostu do wyświetlania informacji w pożądanym, przyjaznym dla ludzi formacie. Dokumentacja firmy Microsoft zawiera więcej informacji na temat składni i możliwości tych funkcji.
Referencje
Przesyłaj i konwertuj (Transact-SQL)
Concat Transact-SQL
Concat_ws Transact-SQL
Łączenie ciągów