Unfortunately, this is an unreliable method of string concatenation in SQL Server. I would avoid it in all but the most trivial of cases. There is some more information in this KB: Execution Plan and Results of Aggregate Concatenation Queries Depend Upon Expression Location.
That said, I was able to both duplicate your problem and provide a workaround in my environment:
SET @val = ''
SELECT @val = @val + 'Hello, my name is ' + replace([name], '', '') + '!' + CHAR(10) + CHAR(13)
FROM LINKED.A.sys.tables
Notice that I've added an empty replace function to the expression. Though it should do nothing to the output, it does add a local "compute scalar" step to the query plan. This seems to pull back all of the data from the name column to then be processed locally rather than just letting the remote query return what it thinks is needed.
I'm not sure if there's a better function to use other than a replace
with empty arguments. Perhaps a double reverse
or something. Just be sure to cast to a max datatype if necessary as the documentation states.
UPDATE
Simply declaring @var
as varchar(max)
rather than nvarchar(max)
clears up the problem, as it then brings back the entire name column (type sysname -- or nvarchar(128) -- I believe) for local processing just like the replace function did. I cannot pretend to know which combination of linked server settings and implicit casting causes this to come up. Hopefully someone with more knowledge in this area can chime-in!