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

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T13:36:42+00:00 2026-06-14T13:36:42+00:00

Is there a better SQL Server 2008 R2 technique to code the following combined

  • 0

Is there a better SQL Server 2008 R2 technique to code the following combined INSERT & UPDATE procedure that allows NULL INSERT?

I am very interested in seeing how other developers write INSERT & UPDATE procedures that can handle NULL inserts (imagine a user wanting to undo an entry). I appreciate there will be more sophisticated and elegant solutions using MERGE or some transaction rollback technique which I am interested in seeing, however, I do ask that you build up your example from first principles as this may result in the post having a wider appeal no matter what the readers T-SQL level.

The basis of this simplistic example is an Orders table tracking stock purchases. The procedure should only allow UPDATES when the OrderStatus is the same or increasing..

OrderStatus  Explanation
-------------------------
     0       Creation
     1       Checking
     2       Placement
     3       Execution
     ...
     8       Settlement

Table structure:

CREATE TABLE Orders(
    OrderID INT IDENTITY,
    Ticker VARCHAR(20) NOT NULL,
    Size DECIMAL(31,15) NULL,
    Price DECIMAL(31,15) NULL,
    OrderStatus TINYINT NOT NULL)

Further, let’s imagine we have the following data so that we can test modifying the data:

SET IDENTITY_INSERT [dbo].[Orders] ON
INSERT INTO [dbo].[Orders] ([OrderID], [Ticker], [Size], [Price], [OrderStatus]) 
VALUES  (1, N'MSFT', CAST(1 AS Decimal(31, 15)), NULL, 0)
        ,(2, N'GOOG', CAST(2 AS Decimal(31, 15)), CAST(523 AS Decimal(31, 15)), 5)
        ,(3, N'AAPL', CAST(1 AS Decimal(31, 15)), NULL, 0)
SET IDENTITY_INSERT [dbo].[Orders] OFF

You should have the following data:

OrderID Ticker  Size    Price   OrderStatus
-----------------------------------------------
1       MSFT    1.000   NULL    0
2       GOOG    2.000   523.000 5
3       AAPL    1.000   NULL    0

Now for the interesting part. This is my best effort to design a combined INSERT & UPDATE procedure that can deal with NULL inserts (i.e. allow the user to undo an entry). Notice that I need an input parameter to differentiate whether the input value of NULL is intentional and needs to be written into the table vs. the NULL that appears as a missing input parameter. Hopefully it’s very clear why I am asking this question as I find my technique very verbose.

CREATE PROCEDURE [dbo].[Upsert_Orders] @isNullInsert BIT = 0
    ,@OrderID INT = NULL
    ,@Ticker VARCHAR(20) = NULL
    ,@Size VARCHAR(100) = NULL
    ,@Price VARCHAR(100) = NULL
    ,@OrderStatus TINYINT = NULL
AS
BEGIN
    IF (@OrderID IS NOT NULL)
        -- First check if @OrderID exists
        IF (
                SELECT OrderID
                FROM dbo.Orders
                WHERE OrderID = @OrderID
                ) IS NULL
        BEGIN
            -- @OrderID does not exist therefore replace with NULL
            SET @OrderID = NULL
            PRINT 'spUO. Replaced OrderID ' + CAST(@OrderID AS VARCHAR) + ' input parameter with NULL.'
        END

    IF @OrderID IS NULL
    BEGIN
        -- @OrderID IS NULL so INSERT a new record
        PRINT 'spUO Inserting a new record into the Orders'

        INSERT INTO Orders (
            -- OrderID not needed as IDENTITY new record.
            Ticker
            ,Size
            ,Price
            ,OrderStatus
            )
        VALUES (
            -- @OrderID not needed as IDENTITY new record
            @Ticker
            ,@Size
            ,@Price
            ,@OrderStatus
            )
    END
    ELSE
    BEGIN
        -- @OrderID IS NOT NULL therefore UPDATE the record @OrderID
        PRINT 'spUO Modifying existing record with OrderID ' + CAST(@OrderID AS VARCHAR)

        -- Declare CurrentVariables for @OrderID
        DECLARE -- @CurrentOrderID INT not needed as @OrderID Found
            @CurrentTicker VARCHAR(20)
            ,@CurrentSize DECIMAL(31, 15)
            ,@CurrentPrice DECIMAL(31, 15)
            ,@CurrentOrderStatus TINYINT

        -- Populate Current Variables from Table Orders
        SELECT -- @CurrentOrderID = OrderID not needed as @OrderID Found
            @CurrentTicker = Ticker
            ,@CurrentSize = Size
            ,@CurrentPrice = Price
            ,@CurrentOrderStatus = OrderStatus
        FROM Orders
        WHERE OrderID = @OrderID

        IF ISNULL(@OrderStatus, @CurrentOrderStatus) >= @CurrentOrderStatus
        BEGIN
            -- Update @OrderID if not moving backwards
            IF @isNullInsert = 0
            BEGIN
                -- We are not updating the record with NULL
                PRINT 'spUO NULL Parameter Input Values get replaced with the existing entries'

                UPDATE Orders
                SET -- OrderID = ISNULL(@OrderID, @CurrentOrderID)  not needed as @OrderID Found
                    Ticker = ISNULL(@Ticker, @CurrentTicker)
                    ,Size = ISNULL(@Size, @CurrentSize)
                    ,Price = ISNULL(@Price, @CurrentPrice)
                    ,OrderStatus = ISNULL(@OrderStatus, @CurrentOrderStatus)
                WHERE OrderID = @OrderID
            END
            ELSE
            BEGIN
                -- We are potentially overwritting the record with NULL
                PRINT 'spUO Old entries may be overwritten with NULL'

                UPDATE Orders
                SET -- OrderID = ISNULL(@OrderID, @CurrentOrderID)  not needed as @OrderID Found
                    Ticker = @Ticker
                    ,Size = @Size
                    ,Price = @Price
                    ,OrderStatus = @OrderStatus
                WHERE OrderID = @OrderID
            END
        END
        ELSE
            -- User is trying to re-write hostory. Do Nothing
            PRINT 'spUO You do not have permissions to roll back the OrderStatus.' 
    END
END

Now that we have an UPSERT procedure, let me illustrate its usage:

Step 1: insert a new row to show the intention to buy some Ford shares:

EXEC dbo.Upsert_Orders  @Ticker = 'F',
                        @Size = 1,
                        @Price = 10,
                        @OrderStatus = 2

Step 2: let’s show that the OrderStatus can’t be wound back

EXEC dbo.Upsert_Orders  @OrderID = 4,
                        @Ticker = 'F',
                        @Size = 1,
                        @Price = 10,
                        @OrderStatus = 1

This produces the desired output:

spUO Modifying existing record with OrderID 4 
spUO You do not have permissions to roll back the OrderStatus.

The data now looks like:

OrderID Ticker  Size    Price   OrderStatus
-----------------------------------------------
1       MSFT    1.000   NULL    0
2       GOOG    2.000   523.000 5
3       AAPL    1.000   NULL    0
4       F       1.000   10.000  2

Step 3: finally, let’s assume the user wants to delete the shares of the first order, then the unfortunate method under my procedure requires the other default parameters be passed and the @isNULLInsert BIT needs to be set to 1.

EXEC dbo.Upsert_Orders  @isNullInsert = 1,
                        @OrderID = 1,
                        @Ticker = 'MSFT',
                        @Size = NULL,
                        @Price = NULL,
                        @OrderStatus = 0

Hopefully this complete example illustrates the concept in adding a new record, updating an existing record and deleting a field of a record. Apologies for the length of this post, but this is the most concise code I was able to produce!

Final data:

OrderID Ticker  Size    Price   OrderStatus
------------------------------------------------
1       MSFT    NULL    NULL    0
2       GOOG    2.000   523.000 5
3       AAPL    1.000   NULL    0
4       F       1.000   10.000  2

Thanks All,

Bertie.

p.s. This will be called from Excel VBA.

  • 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-14T13:36:43+00:00Added an answer on June 14, 2026 at 1:36 pm

    Here’s an answer using merge.

    Create Procedure [dbo].[Upsert_Orders2] 
        @IsNullInsert Bit = 0,
        @OrderID Int = Null,
        @Ticker Varchar(20) = Null,
        @Size Decimal(31,15) = Null,
        @Price Decimal(31,15) = Null,
        @OrderStatus Tinyint = Null
    As
    
    Declare @OrderStatusChange Table(Oldstatus int, NewStatus int)
    
    Begin Transaction
    
    Merge
      dbo.Orders As target
    Using
      (Select @OrderID As OrderID) As source
    On 
      (target.OrderID = source.OrderID)
    When Matched Then
      Update Set
        Ticker = Case When @IsNullInsert = 0 Then IsNull(@Ticker, target.Ticker) Else @Ticker End,
        Size = Case When @IsNullInsert = 0 Then IsNull(@Size, target.Size) Else @Size End,
        Price = Case When @IsNullInsert = 0 Then IsNull(@Price, target.Price) Else @Price End,
        OrderStatus = Case When @IsNullInsert = 0 Then IsNull(@OrderStatus, target.OrderStatus) Else @OrderStatus End
    When Not Matched Then
      Insert 
        (Ticker, Size, Price, OrderStatus)
      Values
        (@Ticker, @Size, @Price, @OrderStatus)
    Output
      deleted.OrderStatus, inserted.OrderStatus into @OrderStatusChange;
    
    If Exists (Select 'x' From @OrderStatusChange Where NewStatus < OldStatus)
      -- Evil History Changer!
      Rollback Transaction
    Else
      Commit Transaction
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Hi all I have the following SQL Server 2008 script that will check if
I'm working with a SQL Server 2008 installation that was maintained for years by
In SQL Server 2008 I would like to create a stored procedure to select
Imagine the following schema and sample data (SQL Server 2008): OriginatingObject ---------------------------------------------- ID 1
I'm using SQL Server 2008. I have a database table that looks like this
I have a view defined in SQL server 2008 that joins 4 tables together.
We are migrating ASP code that used ADO to connect to SQL Server 2000.
Our data resides in a SQL Server 2008 database, there will be a lot
I've inherited a system using SQL Server (2008 R2) with two tables that cover
Is there a better way to code this? def __contains__(self, e): return e in

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.