开发者

Simplify SQL Insert which uses NEWSEQUNETIALID() column default

开发者 https://www.devze.com 2023-01-19 17:35 出处:网络
I have the following insert stored procedure: CREATE Procedure dbo.APPL_ServerEnvironmentInsert ( @ServerEnvironmentName varchar(50),

I have the following insert stored procedure:

CREATE Procedure dbo.APPL_ServerEnvironmentInsert
(
    @ServerEnvironmentName varchar(50),
    @ServerEnvironmentDescription varchar(1000),
    @UserCreatedId uniqueidentifier,
    @ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
    -- Stores the ServerEnvironmentId.
    DECLARE @APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)

    -- If @ServerEnvironmentId was not supplied.
    IF (@ServerEnvironmentId IS NULL)
    BEGIN
        -- Insert the data into the table.
        INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
        (
                ServerEnvir开发者_运维知识库onmentName,
                ServerEnvironmentDescription,
                DateCreated,
                UserCreatedId
        )
        OUTPUT Inserted.ServerEnvironmentId INTO @APPL_ServerEnvironment
        VALUES
        (
                @ServerEnvironmentName,
                @ServerEnvironmentDescription,
                GETDATE(),
                @UserCreatedId
        )

        -- Get the ServerEnvironmentId.
        SELECT @ServerEnvironmentId = ServerEnvironmentId
        FROM @APPL_ServerEnvironment
    END
    ELSE
    BEGIN
        -- Insert the data into the table.
        INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
        (
                ServerEnvironmentId,
                ServerEnvironmentName,
                ServerEnvironmentDescription,
                DateCreated,
                UserCreatedId
        )
        VALUES
        (
                @ServerEnvironmentId,
                @ServerEnvironmentName,
                @ServerEnvironmentDescription,
                GETDATE(),
                @UserCreatedId
        )
    END
GO

I could have simplified the above as:

CREATE Procedure dbo.APPL_ServerEnvironmentInsert
(
    @ServerEnvironmentName varchar(50),
    @ServerEnvironmentDescription varchar(1000),
    @UserCreatedId uniqueidentifier,
    @ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Ensure @ServerEnvironmentId IS NOT NULL
SELECT ISNULL(@ServerEnvironmentId, newid())

-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
    ServerEnvironmentId,
    ServerEnvironmentName,
    ServerEnvironmentDescription,
    DateCreated,
    UserCreatedId
)
VALUES
(
    @ServerEnvironmentId,
    @ServerEnvironmentName,
    @ServerEnvironmentDescription,
    GETDATE(),
    @UserCreatedId
)
GO

But by doing so, i loose the performance improvements of the newsequentialid() over newid(). newsequentialid() can not be set in code as newid(), it can only be supplied as a default value on a table column level.

Any ideas anyone on simplifying the original query, but utilising newsequentialid()? Or, is the original query the most simplified solution in achieving this?


Since the newsequentialid() can only be used as a column default value, you could change your original query to:

  • insert just the @ServerEnvironmentId if no value had been supplied, thus generating a new sequential ID and retrieving it from the OUTPUT clause

  • then update that row defined by either the @ServerEnvironmentId passed in originally, or the new ID you just created by inserting a "dummy row" into your table

Not sure if that would be any faster / more efficient - you would have to do some measurements on that.


Yes. Consider giving the new merge statement a try. It should be 100% compatible with the column default of newsequentialid(), and it will get the SQL down to a single concise statement. I hope this helps.


My original idea was correct. It is the simplest and most readable solution possible.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号