2017-03-06 3 views
1

J'ai une situation unique où j'ai besoin de concaténer des lignes basées sur 2 groupes. L'autre astuce est que la concaténation doit être capable d'afficher des puces et d'ajouter un saut de ligne. C'est ce que demande mon entreprise. Je devrais également ajouter la destination finale sera Excel. J'ai testé l'exportation vers Excel avec SSIS en utilisant des données qui ont des puces et des sauts de ligne et cette pièce fonctionne.Comment concaténer des chaînes Unicode dans SQL Server?

Comment passer de:

pk orgnl_pk type text 
1 1   one • Line One 
2 1   one • Line Two 
3 1   one • Line Three 
4 1   two • Line One 
7 3   one • Line One 
8 3   two • Line One 
9 3   two • Line Two 

Pour:

orgnl_pk type text 
1   one  • Line One 
        • Line Two 
        • Line Three 
1   two  • Line One 
3   one  • Line One 
3   two  • Line One 
        • Line Two 
+3

cela devrait se faire dans la couche de présentation, pas le niveau de base de données – Lamak

+0

Je suis d'accord avec @ Lamak ici. L'entreprise peut demander à ressembler à cela et vous devez fournir cela. Mais la base de données doit renvoyer les données à votre application, puis vous le formater. –

+0

Je suis d'accord avec vous deux, et c'était aussi ma première réponse. Cependant, les outils actuels et le niveau de sécurité à notre disposition au sein de la société exigent que cela soit fait. Je sais que cela peut être fait, c'est juste une question de comment. Je devrais également ajouter la destination finale sera Excel. J'ai testé l'exportation vers Excel avec SSIS en utilisant des données qui ont des puces et des sauts de ligne et cette pièce fonctionne. –

Répondre

1

Comme Lamak a souligné, cela est préférable de laisser à la couche de présentation, mais si vous devez le faire dans sql pour l'instant. .. alors cela utilise le stuff() with select ... for xml path ('') method of string concatenation.

select 
    orgnl_pk 
    , [type] 
    , [text]=stuff(
     (
     select char(10) +i.[text] 
      from t as i 
      where i.orgnl_pk = t.orgnl_pk 
      and i.[type]=t.[type] 
      order by i.pk 
     for xml path (''), type).value('.','nvarchar(max)') 
     ,1,0,'') 
from t 
group by orgnl_pk, [type] 

rextester démonstration: http://rextester.com/GPFIMO37322

retours:

+----------+------+--------------+ 
| orgnl_pk | type |  text  | 
+----------+------+--------------+ 
|  1 | one | • Line One | 
|   |  | • Line Two | 
|   |  | • Line Three | 
|  1 | two | • Line One | 
|  3 | one | • Line One | 
|  3 | two | • Line One | 
|   |  | • Line Two | 
+----------+------+--------------+ 


Mise à jour pour le caractère (0x0007):

select 
    orgnl_pk 
    , [type] 
    , [text]=replace(stuff(
     (
     select char(10)+replace(i.[text],nchar(0x0007),'$BEL$') 
      from t as i 
      where i.orgnl_pk = t.orgnl_pk 
      and i.[type]=t.[type] 
      order by i.pk 
     for xml path (''), type).value('.','nvarchar(max)') 
     ,1,1,''),'$BEL$',nchar(0x0007)) 
from t 
group by orgnl_pk, [type] 
+0

yup, cela fonctionne aussi – Lamak

+0

Merci beaucoup @SqlZim. J'ai substitué les deux tables avec mon nom de table. Est-ce correct? Je reçois cette erreur 'FOR XML n'a pas pu sérialiser les données pour le noeud' NoName 'car il contient un caractère (0x0007) qui n'est pas autorisé en XML. Pour récupérer ces données à l'aide de FOR XML, convertissez-le en type de données binaire, varbinary ou image et utilisez la directive BINARY BASE64 ' –

+0

@ B.C. vous pouvez le remplacer par une chaîne temporaire et le remplacer après le 'pour xml'. J'ai mis à jour la réponse avec une solution de contournement pour cela. - Ou supprimez-le comme indiqué ici: http://dba.stackexchange.com/q/107238/43889 – SqlZim