J'ai une fonction SQL qui comprend ce code:
DECLARE @CodeNameString varchar(100)
SELECT CodeName FROM AccountCodes ORDER BY Sort
Je dois concaténer tous les résultats de la requête sélectionnée dans CodeNameString.
Évidemment, une boucle FOREACH en code C # ferait cela, mais comment puis-je le faire en SQL?
Si vous êtes sur SQL Server 2005 ou supérieur, vous pouvez utiliser cette astuce FOR XML PATH & STUFF
:
DECLARE @CodeNameString varchar(100)
SELECT
@CodeNameString = STUFF( (SELECT ',' + CodeName
FROM dbo.AccountCodes
ORDER BY Sort
FOR XML PATH('')),
1, 1, '')
La FOR XML PATH('')
concatène essentiellement vos chaînes en un seul et long résultat XML (quelque chose comme ,code1,code2,code3
etc.) et la STUFF
place un caractère "rien" au premier caractère, par exemple. supprime la première virgule "superflue" pour vous donner le résultat que vous recherchez probablement.
UPDATE: OK - Je comprends les commentaires - si votre texte dans la table de la base de données contient déjà des caractères tels que <
, >
ou &
, alors ma solution actuelle les encodera en <
, >
et &
.
Si vous avez un problème avec ce codage XML - alors oui, vous devez également consulter la solution proposée par @KM, qui fonctionne également pour ces caractères. Un mot de avertissement de moi: cette approche est beaucoup plus beaucoup de ressources et de traitement - comme vous le savez.
DECLARE @CodeNameString varchar(max)
SET @CodeNameString=''
SELECT @CodeNameString=@CodeNameString+CodeName FROM AccountCodes ORDER BY Sort
SELECT @CodeNameString
La réponse de @ AlexanderMP est correcte, mais vous pouvez également envisager de traiter les valeurs null avec coalesce
:
declare @CodeNameString nvarchar(max)
set @CodeNameString = null
SELECT @CodeNameString = Coalesce(@CodeNameString + ', ', '') + cast(CodeName as varchar) from AccountCodes
select @CodeNameString
Pour SQL Server 2005 et versions ultérieures, utilisez Coalesce for nulls
et j'utilise Cast ou Convert s'il existe numeric values
-
declare @CodeNameString nvarchar(max)
select @CodeNameString = COALESCE(@CodeNameString + ',', '') + Cast(CodeName as varchar) from AccountCodes ORDER BY Sort
select @CodeNameString
from msdn N'utilisez pas de variable dans une instruction SELECT pour concaténer des valeurs (c'est-à-dire pour calculer des valeurs d'agrégat). Des résultats de requête inattendus peuvent se produire. En effet, il n'est pas garanti que toutes les expressions de la liste SELECT (y compris les affectations) soient exécutées exactement une fois pour chaque ligne de sortie.
Ce qui précède semble indiquer que la concaténation effectuée de la manière susmentionnée n’est pas valide, car l’attribution pourrait être effectuée plus de fois que le nombre de lignes renvoyées par la sélection
Voici un autre exemple concret qui fonctionne bien au moins avec la version 2008 (et ultérieure).
C'est la requête originale qui utilise la simple max()
pour obtenir au moins une des valeurs:
SELECT option_name, Field_M3_name, max(Option_value) AS "Option value", max(Sorting) AS "Sorted"
FROM Value_list group by Option_name, Field_M3_name
ORDER BY option_name, Field_M3_name
Version améliorée, où l'amélioration principale consiste à afficher toutes les valeurs séparées par des virgules:
SELECT from1.keys, from1.option_name, from1.Field_M3_name,
Stuff((SELECT DISTINCT ', ' + [Option_value] FROM Value_list from2
WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE)
.value('text()[1]','nvarchar(max)'),1,2,N'') AS "Option values",
Stuff((SELECT DISTINCT ', ' + CAST([Sorting] AS VARCHAR) FROM Value_list from2
WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE)
.value('text()[1]','nvarchar(max)'),1,2,N'') AS "Sorting"
FROM ((SELECT DISTINCT COALESCE(Option_name,'') + '|' + COALESCE(Field_M3_name,'') AS keys, Option_name, Field_M3_name FROM Value_list)
-- WHERE
) from1
ORDER BY keys
Notez que nous avons résolu tous les problèmes de cas NULL
possibles auxquels je peux penser et nous avons également corrigé une erreur que nous avons eue pour les valeurs numériques (champ Tri).