Niestety jest to zawodna metoda łączenia ciągów w SQL Server. Unikałbym tego we wszystkich, z wyjątkiem najbardziej trywialnych przypadków. W tej bazie wiedzy znajduje się więcej informacji:Plan wykonania i wyniki zagregowanych zapytań konkatenacyjnych zależą od Lokalizacja wyrażenia .
To powiedziawszy, udało mi się zarówno zduplikować Twój problem, jak i zapewnić obejście w moim środowisku:
SET @val = ''
SELECT @val = @val + 'Hello, my name is ' + replace([name], '', '') + '!' + CHAR(10) + CHAR(13)
FROM LINKED.A.sys.tables
Zauważ, że dodałem pustą funkcję replace do wyrażenia. Chociaż nie powinien nic robić na wyjściu, dodaje lokalny krok "oblicz skalarny" do planu zapytania. Wydaje się, że powoduje to wycofanie wszystkich danych z kolumny nazwy, aby następnie przetworzyć je lokalnie, zamiast pozwalać, aby zdalne zapytanie zwróciło to, co uważa za potrzebne.
Nie jestem pewien, czy istnieje lepsza funkcja do użycia niż replace
z pustymi argumentami. Być może podwójny reverse
lub coś. Tylko pamiętaj, aby w razie potrzeby rzutować na maksymalny typ danych, zgodnie z dokumentacją.
AKTUALIZUJ
Wystarczy zadeklarować @var
jako varchar(max)
zamiast nvarchar(max)
rozwiązuje problem, ponieważ następnie zwraca całą kolumnę nazwy (typ sysname — lub nvarchar(128) — jak sądzę) do przetwarzania lokalnego, tak jak zrobiła to funkcja replace. Nie mogę udawać, że wiem, która kombinacja ustawień serwera połączonego
a niejawne rzucanie powoduje, że to się pojawia. Mam nadzieję, że ktoś z większą wiedzą w tej dziedzinie może się włączyć!