EN VI

Throwing exception in SQL MERGE clause is not possible?

2024-03-10 22:30:05
Throwing exception in SQL MERGE clause is not possible

I want to merge 2 tables only if all of the IDs in the source table exist in the target table. But it is not possible to throw exceptions inside merge clause. What are my alternative options to achieve the same result?

I tried this:

MERGE [dbo].[Target] as tgt
USING [dbo].[Source] as src
ON (tgt.ID = src.ID)
WHEN MATCHED THEN
    UPDATE SET tgt.Name = src.Name
WHEN NOT MATCHED THEN 
    THROW 51000, 'error: not all ids match!', 1;

I expected it to update the target table only if the source table has all the IDs there are in the target table but instead, I got an error saying:

Incorrect syntax near 'THROW'. Expecting DELETE, INSERT, or UPDATE.

Solution:

You can't use arbitrary statements in the THEN part of a MERGE, the syntax is quite specific about what you are allowed to do.

If you want to THROW on such rows then just use a IF EXISTS... WHERE NOT EXISTS. And then convert the MERGE into a normal joined UPDATE.

Since it's now two statements, you are going to need an explicit transaction and locking hints.

SET NOCOUNT, XACT_ABORT ON;

BEGIN TRAN;

IF EXISTS (SELECT 1
    FROM dbo.Source as src WITH (SERIALIZABLE)
    WHERE NOT EXISTS (SELECT 1
        FROM dbo.Target as tgt WITH (SERIALIZABLE, UPDLOCK)
        WHERE tgt.ID = src.ID
    )
)
    THROW 50001, N'error: not all ids match!', 1


UPDATE tgt
SET Name = src.Name
FROM dbo.Target as tgt
JOIN dbo.Source as src ON tgt.ID = src.ID;

COMMIT;
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login