Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

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

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6599459
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T18:29:37+00:00 2026-05-25T18:29:37+00:00

We have a process updating the database which uses the following SQL IF NOT

  • 0

We have a process updating the database which uses the following SQL

IF NOT EXISTS (SELECT * FROM Target_Table WHERE Target_Table_ID = ...)
BEGIN
    INSERT ...
END
ELSE
BEGIN
    UPDATE ...
END

I wanted to change this to use a MERGE statement in order to avoid a possible race condition where the IF and then INSERT or UPDATE statements are evaluated separately.

However, as soon as I executed the query I got the error:

The target table ‘Target_Table’ of the MERGE statement cannot have any enabled rules. Found rule ‘TargetTable_RULE’

I understand the documentation states that the table cannot have rules enabled, although I missed it when first reading it, and apart from disabling the rule before performing the MERGE (which I don’t see as a workable solution) it seems I’m stuck with the IF NOT EXISTS solution.

What the document does not explain is why the target table is not allowed to have rules. In my case the rule is a simple > 0 check on a value.

Does anyone know why rules are not allowed in this situation and if there is another way to perform the upsert in an atomic way?

EDIT: As Andriy M commented the question Atomic UPSERT in SQL Server 2005 already has a wealth of information on atomic upserts so I’ll not duplicate the discussion here. Instead I’d like just to know why the MERGE statement cannot execute on tables with rules defined and is there a work-around?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T18:29:38+00:00Added an answer on May 25, 2026 at 6:29 pm
    • Rules are old feature of SQL Server.
    • This feature will be removed in a future version of Microsoft SQL Server.. I think, this is the reason why MERGE statement does not supports tables with rules.
    • You can replace rules with check constraints.

    MERGE example (with rules & with CHECK constraints):

    CREATE RULE MyRule
    AS 
    @Status IN ('Y', 'N');
    GO
    
    CREATE TABLE dbo.SalesOrder
    (
        SalesOrderID INT PRIMARY KEY
        ,OrderDate DATETIME NOT NULL
        ,IsDeleted CHAR(1) NOT NULL DEFAULT 'N'
    );
    GO
    
    EXEC sp_bindrule @rulename='MyRule', @objname='dbo.SalesOrder.IsDeleted';
    GO
    
    INSERT  dbo.SalesOrder (SalesOrderID, OrderDate)
    SELECT  1, '20110101'
    UNION ALL
    SELECT  2, '20110202'
    UNION ALL
    SELECT  3, '20110303';
    GO
    
    SELECT  *
    FROM    dbo.SalesOrder;
    
    PRINT '*****First test*****';
    GO
    
    MERGE   dbo.SalesOrder Dst
    USING   (VALUES (1,'Y'), (4,'Y')) AS Src(SalesOrderID, IsDeleted) 
    ON      Dst.SalesOrderID = Src.SalesOrderID
    WHEN    MATCHED THEN UPDATE SET IsDeleted = Src.IsDeleted
    WHEN    NOT MATCHED BY TARGET THEN INSERT (SalesOrderID, OrderDate, IsDeleted) VALUES (Src.SalesOrderID, GETDATE(), Src.IsDeleted);
    GO
    
    EXEC sp_unbindrule 'dbo.SalesOrder.IsDeleted'; --Disabling `MyRule` for IsDeleted column
    ALTER TABLE dbo.SalesOrder --We "replace" the old rule with a new `CHECK` constraint
    ADD CONSTRAINT CK_SalesOrder_IsDeleted CHECK( IsDeleted IN ('Y', 'N') );
    GO
    
    PRINT '*****Second test*****';
    MERGE   dbo.SalesOrder Dst
    USING   (VALUES (1,'Y'), (4,'Y')) AS Src(SalesOrderID, IsDeleted) 
    ON      Dst.SalesOrderID = Src.SalesOrderID
    WHEN    MATCHED THEN UPDATE SET IsDeleted = Src.IsDeleted
    WHEN    NOT MATCHED BY TARGET THEN INSERT (SalesOrderID, OrderDate, IsDeleted) VALUES (Src.SalesOrderID, GETDATE(), Src.IsDeleted);
    GO
    
    SELECT  *
    FROM    dbo.SalesOrder;
    
    DROP TABLE dbo.SalesOrder;
    DROP RULE MyRule;
    

    Results:

    Rule bound to table column.
    
    (3 row(s) affected)
    SalesOrderID OrderDate               IsDeleted
    ------------ ----------------------- ---------
    1            2011-01-01 00:00:00.000 N
    2            2011-02-02 00:00:00.000 N
    3            2011-03-03 00:00:00.000 N
    
    (3 row(s) affected)
    
    *****First test*****
    Msg 358, Level 16, State 1, Line 2
    The target table 'Dst' of the MERGE statement cannot have any enabled rules.  Found rule 'MyRule'.
    Rule unbound from table column.
    *****Second test*****
    
    (2 row(s) affected)
    SalesOrderID OrderDate               IsDeleted
    ------------ ----------------------- ---------
    1            2011-01-01 00:00:00.000 Y
    2            2011-02-02 00:00:00.000 N
    3            2011-03-03 00:00:00.000 N
    4            2011-09-20 16:03:56.030 Y
    
    (4 row(s) affected)
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have Process objects that are monitored from two different views. A Windows.Forms.ListView (actually
I have 1 process that receives incoming connection from port 1000 in 1 linux
I have a process in a website (Asp.net 3.5 using Linq-to-Sql for data access)
I have a process which has a notify method which receives as a parameter
I have a MySQL 5 database that is updated every 5 minutes from a
I am in the process of updating some tables in my database and I
I'm updating a program for my company that requires the user to have SQL
I have the following scenario: User X logs in to the application from location
I'm in the process of converting a system from sql server to mongodb. I
I have a process in erlang that is supposed to do something immediately after

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.