はじめに
顧客データを含むテーブルを管理していて、上司から顧客の現在のリストとその電話番号を送信するように求められたとします。通常、データを抽出して、行と列を含むスプレッドシートを送信します。また、少しスタイリッシュにして、必要な情報をより人に優しい形式で送信することもできます。 SQL Serverは、英語の式とテーブル内のデータを組み合わせて、技術者以外の人が読みやすい出力を表示することで、これを実現できる関数を提供します。これらの機能は、より微妙な用途にも使用できます。
CONCAT関数
CONCAT関数は、2つ以上の文字列引数を受け入れ、そのような文字列の組み合わせを1つの式として返します。これは、さまざまな列の内容を単一の式として表示する場合に役立ちます。この関数の簡単な使用例をリスト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
図1のスペースと結果を使用したこのステートメントのバリエーションに注意してください。
図。 1.単純なCONCATステートメント
INTデータ型の入力値でCONCATステートメントを使用しようとすると、SQL Serverは暗黙の変換を実行し、図2に示すように文字列出力を返します。これは、リスト2のステートメントの詳細。まず、関心のあるテーブルの構造を見てください。図2は、 PhoneNumber#を示しています。 およびFirstTranDate 列はそれぞれBIGINT列とDATETIME列です。
図。 2.顧客テーブルの構造
-- Listing 2: Implicit Conversion When using CONCAT (BIGINT) USE EXAM GO SELECT CONCAT(firstname , ' ' ,lastname , '''s ' , 'Phone number is ' ,phonenumber1) FROM CUSTOMER;
実行プランをざっと見てみると、SQLServerが暗黙の変換を実行していることがわかります。 PhoneNumber1列。これは、列がリスト4と図4に示す日付データ型の場合も同じです。CONCAT関数は、図6に示すグラフに概説されているルールに基づいて暗黙的な変換を実行します。
図。 3.BIGINTデータ型の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;
図。 4.の暗黙的な変換 DATETIMEデータ型からVARCHAR
図。 5.BIGINTデータ型のVARCHARへの暗黙的な変換
図。 6.SQLServerでのデータ型変換
この関数の主な使用例は、上記のデモンストレーションから推測できます。例としては、ダッシュボードやWebページに、複数の列や個別のテーブルのデータを使用して、よりわかりやすい言語で情報を表示する必要がある場合があります。
CONCAT_WS関数
CONCAT_WS関数は、CONCAT関数の拡張です。これにより、最初のパラメーターとして目的のセパレーターを指定できます。リスト4は、リスト1で以前に使用したステートメントの1つを変更したものです。
--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;
CONCAT_WSを使用すると、各引数の後に引数としてスペースを導入する場合に比べて、区切り文字としてスペースを使用してステートメントを簡単に作成できることに注意してください。
--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;
「+」記号との連結
SQL Serverは、「+」記号の使用をサポートして、CONCAT関数がはるかに簡単な方法で実行することを実現します。このアプローチは通常、多数のオブジェクトに対して操作を実行する必要がある場合にT-SQLステートメントを生成するために使用されます。リスト7は、Examデータベース内のすべてのテーブルの統計更新バッチを生成する方法を示しています。
-- 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
2番目のステートメントの角括弧に注意してください。スペースや特殊文字を含むシステムオブジェクトを処理する場合に便利です。
-- 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
出力が生成されると、リスト7に示すように、任意のデータベースにユーザーを作成するために使用できます。関心のあるログイン名のフィルターを追加したことに注意してください。このアプローチは、あらゆる種類のステートメントを生成するために使用できます。同じセッション内でそのようなステートメントを呼び出します。より複雑な例は、データベース内のすべてのインデックスを創造的に再構築する次のステートメントです。 (リスト8および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
リスト10のクエリは、文字列を明示的に文字列に変換された日付と組み合わせる方法を示しています。 文字列の連結 後で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'
結論
この記事では、SQLServerで連結を使用するいくつかの方法を示しました。 CONCAT関数、CONCAT_WS関数、および「+」記号の使用例を示しました。 3つの方法はすべて、異なる列の値を組み合わせてステートメントを生成したり、単に情報を必要な人にわかりやすい形式で表示したりするのに非常に役立ちます。 Microsoftのドキュメントには、これらの関数の構文と機能に関する詳細情報があります。
参照
キャストと変換(Transact-SQL)
Concat Transact-SQL
Concat_ws Transact-SQL
文字列の連結