0

I have set up a linked server connection from my on-premise to Azure called AZURE. When I run the following code, it errors out:

DECLARE @DynamicSQL NVARCHAR(MAX)='

MERGE [AZURE].[Test].[dbo].[Persons] AS TARGET
USING [Test].[dbo].Persons AS SOURCE ON (TARGET.ID = SOURCE.ID) 

-- When records are matched, update the records if there is any change
WHEN MATCHED AND TARGET.LastName <> SOURCE.LastName OR TARGET.FirstName <> SOURCE.FirstName OR TARGET.Age <> SOURCE.Age
THEN 
    UPDATE 
        SET TARGET.LastName = SOURCE.LastName, 
            TARGET.FirstName = SOURCE.FirstName, 
            TARGET.Age = SOURCE.Age;'

EXECUTE (@DynamicSQL) AT AZURE

The error message is the following:

The target of a MERGE statement cannot be a remote table, a remote view, or a view over remote tables.

Attempted to make the MERGE statement as simple as possible for testing purposes but the same error is still returned.

9
  • 1
    You seem to be expecting the AZURE server to understand [Test].[dbo].Persons as your local [Test].[dbo].Persons? It's going to understand [Test].[dbo].Persons as its [Test].[dbo].Persons, and it's going to reject the [AZURE].[Test].[dbo].[Persons] for being a four-part name, thus referring to a remote server. And if it didn't reject it by recognizing [AZURE] is actually its own name, it would be merging that table into itself. Commented Mar 6, 2024 at 22:00
  • The error is clear, you can't merge into a linked database table? It doesn't matter what you change, while you have the same target you'll get the same error. Commented Mar 6, 2024 at 22:01
  • Why use MERGE at all? This is a single UPDATE. MERGE has several quirks and in this case it's not needed at all. In general, MERGE is hardly better than separate UPDATA and INSERT statements. Don't expect good performance though - to find out matching rows the database server will have to pull all the data from the remote server and perform the JOIN locally. Commented Mar 7, 2024 at 10:28
  • You can limit the number of rows to only the changed ones if you use change tracking on the source server and thus use only the rows inserted or updated since the last run, eg INSERT INTO [AZURE].[Test].[dbo].[Persons](...) SELECT ... FROM [Test].[dbo].Persons AS P INNER JOIN CHANGETABLE(CHANGES [Test].[dbo].Persons, @last_synchronization_version) AS CT ON P.ID= CT.tID AND CT.SYS_CHANGE_OPERATION = 'I'; Commented Mar 7, 2024 at 10:34
  • You can do the same for UPDATE. You'll have to make sure the remote table is the first one in the JOIN, to ensure the changes are sent to Azure and the join performed there, eg : UPDATE ... FROM Remote INNER JOIN (SELECT ID,... From LocalTable INNER JOIN CHANGETABLE(CHANGES LocalTable, @last_synchronization_version) AS CT ON P.ID= CT.tID AND CT.SYS_CHANGE_OPERATION = 'U') c on Remote.ID=C.ID ; Commented Mar 7, 2024 at 10:46

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.