Présentation
Supposons que vous teniez à jour une table contenant les données des clients et que votre patron vous demande de lui envoyer la liste actuelle des clients et leurs numéros de téléphone. Vous extrayez généralement les données et lui envoyez une feuille de calcul avec des lignes et des colonnes. Vous pouvez également décider d'être un peu stylé et lui envoyer les informations requises dans un format plus convivial. SQL Server fournit des fonctions qui nous permettent d'y parvenir en combinant des expressions anglaises avec des données dans des tables pour présenter une sortie plus facile à lire pour les personnes non techniques. Ces fonctions peuvent également être utilisées à des fins plus subtiles.
La fonction CONCAT
La fonction CONCAT accepte deux ou plusieurs arguments de chaîne et renvoie la combinaison de ces chaînes sous la forme d'une expression unique. Cela peut être utile si vous souhaitez afficher le contenu de différentes colonnes sous la forme d'une seule expression. Un exemple simple d'utilisation de cette fonction est présenté dans le Listing 1.
-- Listing 1 :Déclaration CONCAT simpleselect CONCAT('This','Function','joins','strings.') as statement1;select CONCAT('This ','Function ','joins ','strings.') .') as statement2;select CONCAT('This',' ','Function',' ','joins',' ','strings') as statement
Notez les variations de cette déclaration en utilisant l'espace et les résultats de la Fig. 1.
Fig. 1. Déclaration CONCAT simple
Si nous essayons d'utiliser l'instruction CONCAT avec une valeur d'entrée de type de données INT, SQL Server effectue une conversion implicite et renvoie toujours une sortie de chaîne, comme illustré à la figure 2. Nous pouvons confirmer que c'est ce qui se passe réellement en creusant profondément dans le détails de la déclaration dans le Listing 2. Tout d'abord, jetez un œil à la structure de la table qui nous intéresse. La Fig 2 nous montre que le PhoneNumber# et FirstTranDate les colonnes sont respectivement les colonnes BIGINT et DATETIME.
Fig. 2. Structure de la table des clients
-- Liste 2 :Conversion implicite lors de l'utilisation de CONCAT (BIGINT)USE EXAMGOSELECT CONCAT(firstname, ' ',lastname, '''s ', 'Phone number is ',phonenumber1) FROM CUSTOMER;
Un rapide coup d'œil au plan d'exécution nous montre que SQL Server effectue une conversion implicite dans la colonne PhoneNumber1. Ce sera la même chose si la colonne était le type de données de date comme indiqué dans la liste 4 et la figure 4. La fonction CONCAT effectue une conversion implicite basée sur les règles décrites dans le tableau illustré à la figure 6.
Fig. 3. Conversion implicite du type de données BIGINT en VARCHAR
-- Listing 3 :Conversion implicite lors de l'utilisation de CONCAT (DATETIME)USE EXAMGOSELECT FirstTranDate, CONCAT(FirstName, ' ',LastName, '''s ', 'first transaction date is ',FirstTranDate) as STMTFROM CUSTOMER;
Fig. 4. Conversion implicite de DATETIME type de données à VARCHAR
Fig. 5. Conversion implicite du type de données BIGINT en VARCHAR
Fig. 6. Conversion de type de données dans SQL Server
Le cas d'utilisation principal de cette fonction peut être déduit des démonstrations ci-dessus. Un exemple serait un cas où certaines informations doivent être affichées sur un tableau de bord ou une page Web dans un langage plus convivial en utilisant des données provenant d'un certain nombre de colonnes ou même de tableaux séparés.
La fonction CONCAT_WS
La fonction CONCAT_WS est une extension de la fonction CONCAT. Cela nous permet de spécifier un séparateur souhaité comme premier paramètre. Le Listing 4 nous montre une modification de l'une des déclarations que nous avons précédemment utilisées dans le Listing 1.
--Listing 4 Utilisation de CONCAT_WSSELECT CONCAT('This',' ','Function',' ','joins',' ','strings') AS instruction;SELECT CONCAT('This',' ',' Function',' ','joins',' ','strings') AS instruction;SELECT CONCAT_WS(' ','This','Function','joins','strings') AS statement;Notez que CONCAT_WS simplifie la construction d'une instruction avec un espace comme séparateur par rapport à l'introduction d'un espace comme argument après chaque argument.
--Listing 5 Utilisation de CONCAT_WS avec des colonnesUSE EXAMGOSELECT CONCAT(firstname, ' ',lastname, '''s ', 'Phone number is ',phonenumber1) FROM CUSTOMER;USE EXAMGOSELECT CONCAT_WS(' ',firstname,lastname, ' ''s ', 'Le numéro de téléphone est',numérodetéléphone1) DU CLIENT ;Concaténation avec le signe "+"
SQL Server prend en charge l'utilisation du signe "+" pour réaliser ce que la fonction CONCAT fait d'une manière beaucoup plus simple. Cette approche est généralement utilisée pour générer des instructions T-SQL lorsque vous devez effectuer des opérations sur un grand nombre d'objets. Le Listing 7 montre comment nous pouvons générer un lot de mise à jour des statistiques pour toutes les tables de la base de données d'examen.
-- Listing 6 Génération de déclarations de statistiques de mise à jourUSE ExamGOSELECT 'UPDATE STATISTICS ' + name + ' WITH SAMPLE 25 PERCENT;' comme STMT à partir de sys.tables ; SELECT 'UPDATE STATISTICS [' + name + '] WITH SAMPLE 25 PERCENT;' comme STMT à partir de sys.tables ;GORemarquez les crochets dans la deuxième déclaration. Il est utile lorsqu'il s'agit d'un objet système avec des espaces ou des caractères spéciaux.
-- Listing 7 Génération d'instructions Create UserUSE MASTERGOSELECT 'CREATE USER [' + LOGINNAME + '] FOR LOGIN [' + LOGINNAME + '];' AS STMT FROM SYSLOGINSWHERE LOGINNAME NOT LIKE '#%';GOUSE EXAMGOCREATE 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] POUR LA CONNEXION [NT Service\MSSQL$I2019]; CRÉER UTILISATEUR [NT AUTHORITY\SYSTEM] POUR CONNEXION [NT AUTHORITY\SYSTEM];CRÉER UTILISATEUR [NT SERVICE\SQLAgent$I2019] POUR CONNEXION [NT SERVICE\SQLAgent$I2019];CRÉER UTILISATEUR [NT SERVICE\SQLTELEMETRY$I2019] POUR SE CONNECTER [NT SERVICE\SQLTELEMETRY$I2019];CRÉER UTILISATEUR [KAIROSAFRIKA\sberko] POUR SE CONNECTER [KAIROSAFRIKA\sberko];GOUne fois la sortie générée, elle peut être utilisée pour créer des utilisateurs dans n'importe quelle base de données souhaitée, comme indiqué dans le Listing 7. Notez que nous avons ajouté un filtre pour les noms de connexion qui nous intéressent. Cette approche peut être utilisée pour générer toutes sortes de déclarations. et appeler ces déclarations au cours de la même session. Un exemple plus complexe est les instructions suivantes qui reconstruisent de manière créative tous les index dans n'importe quelle base de données. (Voir Listings 8 et 9).
--Listing 8 Génération d'instructions de reconstruction d'indexUSE 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) + '] RECONSTRUIRE AVEC (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) AS A 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;SELECT * FROM #INDTAB;GODROP TABLE #INDTAB;GO--Listing 9 Génération et exécution d'instructions de reconstruction d'indexUSE 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) + '] RECONSTRUIRE AVEC (EN LIGNE =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 ) AS A 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 @SQL NVARCHAR(4000); SELECT @SQL=REBUILDSTMT FROM #INDTAB ;PRINT @SQLEXEC SP_EXECUTESQL @SQL;GODROP TABLE #INDTAB;GOLa requête du Listing 10 montre comment nous pouvons combiner des chaînes avec des dates explicitement converties en chaînes. La concaténation de chaînes est utilisé pour générer une variable de chemin de sauvegarde commune qui est ensuite utilisée dans la fonction SP_MSFOREACHDB.
--Liste 10 Génération d'un chemin de sauvegarde communEXEC SP_MSFOREACHDB @COMMAND1='DECLARE @BACKUP SYSNAMESET @BACKUP=N''G:\BACKUP\?''+CONVERT(NVARCHAR,GETDATE(),112)+N'' .BAK''USE [?]IF ''?'' NOT IN ("MODEL","TEMPDB")BEGINBACKUP DATABASE ? TO DISK =@BACKUP WITH INIT , NOUNLOAD , COMPRESSION,NAME =N''?'', NOSKIP , NOFORMATEND'Conclusion
Dans cet article, nous avons montré quelques façons d'utiliser la concaténation dans SQL Server. Nous avons donné des exemples de la fonction CONCAT, de la fonction CONCAT_WS et de l'utilisation du signe "+". Les trois méthodes peuvent être très utiles pour générer des déclarations en combinant des valeurs de différentes colonnes ou simplement pour afficher des informations dans un format convivial souhaité. La documentation Microsoft contient plus d'informations sur la syntaxe et les capacités de ces fonctions.
Références
Diffuser et convertir (Transact-SQL)
Concat Transact-SQL
Concat_ws Transact-SQL
Concaténation de chaînes