This has been killing me all day =D. Please help!
Scenario 1: Two DB’s on the same server (A, B) and A has three tables. Query is executed from B.
Scenario 2: Two DB’s one server is linked to the other. (B has link A) and A has three tables. Query is executed from B.
In scenario 1 (non linked server):
SET @val = ''
SELECT @val = @val + 'Hello, my name is ' + [name] + '!' + CHAR(10) + CHAR(13)
FROM A.sys.tables
Returns:
Hello, my name is Table1!
Hello, my name is Table2!
Hello, my name is Table3!
In scenario 2 (linked server):
SET @val = ''
SELECT @val = @val + 'Hello, my name is ' + [name] + '!' + CHAR(10) + CHAR(13)
FROM LINKED.A.sys.tables
Returns:
Hello, my name is Table3!
Why are these different? If I use openquery() on the linked server the results are the same as scenario 1. I’m trying to avoid using openquery() if possible. Thanks!
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:
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
replacewith empty arguments. Perhaps a doublereverseor something. Just be sure to cast to a max datatype if necessary as the documentation states.UPDATE
Simply declaring
@varasvarchar(max)rather thannvarchar(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!