Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Pourquoi est-ce que j'obtiens ces résultats différents à partir de deux requêtes SQL ?

Malheureusement, il s'agit d'une méthode peu fiable de concaténation de chaînes dans SQL Server. Je l'éviterais dans tous les cas, sauf les plus triviaux. Il y a plus d'informations dans ce KB :Le plan d'exécution et les résultats des requêtes de concaténation agrégée dépendent de Emplacement de l'expression .

Cela dit, j'ai pu à la fois dupliquer votre problème et proposer une solution de contournement dans mon environnement :

SET @val = ''
SELECT @val = @val + 'Hello, my name is ' + replace([name], '', '') + '!' + CHAR(10) + CHAR(13)
FROM LINKED.A.sys.tables

Notez que j'ai ajouté une fonction de remplacement vide à l'expression. Bien qu'il ne doive rien faire à la sortie, il ajoute un élément local étape "compute scalar" au plan de requête. Cela semble retirer toutes les données de la colonne de nom pour ensuite les traiter localement plutôt que de simplement laisser la requête distante renvoyer ce qu'elle pense être nécessaire.

Je ne sais pas s'il existe une meilleure fonction à utiliser autre qu'un replace avec des arguments vides. Peut-être un double reverse ou quelque chose. Assurez-vous simplement de convertir en un type de données max si nécessaire, comme l'indique la documentation.

MISE À JOUR

Déclarer simplement @var comme varchar(max) plutôt que nvarchar(max) résout le problème, car il ramène ensuite la colonne de nom entière (type sysname -- ou nvarchar(128) -- je crois) pour le traitement local, tout comme la fonction de remplacement l'a fait. Je ne peux pas prétendre savoir quelle combinaison de paramètres de serveur liés et le casting implicite le fait apparaître. J'espère que quelqu'un ayant plus de connaissances dans ce domaine pourra intervenir !