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 8801837
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T00:56:10+00:00 2026-06-14T00:56:10+00:00

I’m performing an UPDATE with OUTPUT query: UPDATE BatchReports SET IsProcessed = 1 OUTPUT

  • 0

I’m performing an UPDATE with OUTPUT query:

UPDATE BatchReports
SET IsProcessed = 1
OUTPUT inserted.BatchFileXml, inserted.ResponseFileXml, deleted.ProcessedDate
WHERE BatchReports.BatchReportGUID = @someGuid

This statement is well and fine; until a trigger is defined on the table. Then my UPDATE statement will get the error 334:

The target table ‘BatchReports’ of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause

Now this problem is explained in a blog post by the SQL Server team — UPDATE with OUTPUT clause – Triggers – and SQLMoreResults:

The error message is self-explanatory

And they also give solutions:

The application was changed to utilize the INTO clause

Except I cannot make head nor tail of the entirety of the blog post.

So let me ask my question: What should I change my UPDATE to so that it works?

See also

  • UPDATE with OUTPUT clause – Triggers – and SQLMoreResults
  • Why is the target table of a MERGE statement not allowed to have enabled rules?
  • Statement contains an OUTPUT clause without INTO clause error
  • 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-06-14T00:56:11+00:00Added an answer on June 14, 2026 at 12:56 am

    Given the kludge needed to make UPDATE with OUTPUT work in SQL Server 2008 R2, I changed my query from:

    UPDATE BatchReports  
    SET IsProcessed = 1
    OUTPUT inserted.BatchFileXml, inserted.ResponseFileXml, deleted.ProcessedDate
    WHERE BatchReports.BatchReportGUID = @someGuid
    

    to:

    SELECT BatchFileXml, ResponseFileXml, ProcessedDate FROM BatchReports
    WHERE BatchReports.BatchReportGUID = @someGuid
    
    UPDATE BatchReports
    SET IsProcessed = 1
    WHERE BatchReports.BatchReportGUID = @someGuid
    

    Basically I stopped using OUTPUT. This isn’t so bad as Entity Framework itself uses this very same hack!

    Hopefully 2012 2014 2016 2018 2019 2020 will have a better implementation.


    Update: using OUTPUT is harmful

    The problem we started with was trying to use the OUTPUT clause to retrieve the "after" values in a table:

    UPDATE BatchReports
    SET IsProcessed = 1
    OUTPUT inserted.LastModifiedDate, inserted.RowVersion, inserted.BatchReportID
    WHERE BatchReports.BatchReportGUID = @someGuid
    

    That then hits the well-know limitation ("won’t-fix" bug) in SQL Server:

    The target table ‘BatchReports’ of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause

    Workaround Attempt #1

    So we try something where we will use an intermediate TABLE variable to hold the OUTPUT results:

    DECLARE @t TABLE (
       LastModifiedDate datetime,
       RowVersion timestamp, 
       BatchReportID int
    )
      
    UPDATE BatchReports
    SET IsProcessed = 1
    OUTPUT inserted.LastModifiedDate, inserted.RowVersion, inserted.BatchReportID
    INTO @t
    WHERE BatchReports.BatchReportGUID = @someGuid
    
    SELECT * FROM @t
    

    Except that fails because you’re not allowed to insert a timestamp into the table (even a temporary table variable).

    Workaround Attempt #2

    We secretly know that a timestamp is actually a 64-bit (aka 8 byte) unsigned integer. We can change our temporary table definition to use binary(8) rather than timestamp:

    DECLARE @t TABLE (
       LastModifiedDate datetime,
       RowVersion binary(8), 
       BatchReportID int
    )
      
    UPDATE BatchReports
    SET IsProcessed = 1
    OUTPUT inserted.LastModifiedDate, inserted.RowVersion, inserted.BatchReportID
    INTO @t
    WHERE BatchReports.BatchReportGUID = @someGuid
    
    SELECT * FROM @t
    

    And that works, except that the value are wrong.

    The timestamp RowVersion we return is not the value of the timestamp as it existed after the UPDATE completed:

    • returned timestamp: 0x0000000001B71692
    • actual timestamp: 0x0000000001B71693

    That is because the values OUTPUT into our table are not the values as they were at the end of the UPDATE statement:

    • UPDATE statement starting
      • modifies row
        • timestamp is updated (e.g. 2 → 3)
      • OUTPUT retrieves new timestamp (i.e. 3)
      • trigger runs
        • modifies row again
          • timestamp is updated (e.g. 3 → 4)
    • UPDATE statement complete
    • OUTPUT returns 3 (the wrong value)

    This means:

    • We do not get the timestamp as it exists at the end of the UPDATE statement (4)
    • Instead we get the timestamp as it was in the indeterminate middle of the UPDATE statement (3)
    • We do not get the correct timestamp

    The same is true of any trigger that modifies any value in the row. The OUTPUT will not OUTPUT the value as of the end of the UPDATE.

    This means you cannot trust OUTPUT to return any correct values ever.

    This painful reality is documented in the BOL:

    Columns returned from OUTPUT reflect the data as it is after the INSERT, UPDATE, or DELETE statement has completed but before triggers are executed.

    How did Entity Framework solve it?

    The .NET Entity Framework uses rowversion for Optimistic Concurrency. The EF depends on knowing the value of the timestamp as it exists after they issue an UPDATE.

    Since you cannot use OUTPUT for any important data, Microsoft’s Entity Framework uses the same workaround that I do:

    Workaround #3 – Final – Do not use OUTPUT clause

    In order to retrieve the after values, Entity Framework issues:

    UPDATE [dbo].[BatchReports]
    SET [IsProcessed] = @0
    WHERE (([BatchReportGUID] = @1) AND ([RowVersion] = @2))
    
    SELECT [RowVersion], [LastModifiedDate]
    FROM [dbo].[BatchReports]
    WHERE @@ROWCOUNT > 0 AND [BatchReportGUID] = @1
    

    Don’t use OUTPUT.

    Yes it suffers from a race condition, but that’s the best SQL Server can do.

    What about INSERTs

    Do what Entity Framework does:

    SET NOCOUNT ON;
    
    DECLARE @generated_keys table([CustomerID] int)
    
    INSERT Customers (FirstName, LastName)
    OUTPUT inserted.[CustomerID] INTO @generated_keys
    VALUES ('Steve', 'Brown')
    
    SELECT t.[CustomerID], t.[CustomerGuid], t.[RowVersion], t.[CreatedDate]
    FROM @generated_keys AS g
       INNER JOIN Customers AS t
       ON g.[CustomerGUID] = t.[CustomerGUID]
    WHERE @@ROWCOUNT > 0
    

    Again, they use a SELECT statement to read the row, rather than placing any trust in the OUTPUT clause.

    NOTE: In 2022, Entity Framework added a pre-mature optimization bug.

    • in the same way you have to disable any use of OUTPUT in T-SQL
    • you have to disable any use of OUTPUT by Entity Framework

    Microsoft explains how to undo the bug added by #27372:

    modelBuilder.Entity<Blog>().ToTable(tb => tb.UseSqlOutputClause(false));
    

    With the down-side that you have to retroactively apply it to every table you have, or ever will have.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
Let's say I'm outputting a post title and in our database, it's Hello Y&#8217;all
I have a .ini file as follows: [playlist] numberofentries=2 File1=http://87.230.82.17:80 Title1=(#1 - 365/1400) Example
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but
For some reason, after submitting a string like this Jack’s Spindle from a text
I am reading a book about Javascript and jQuery and using one of the

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.