Simplify SQL Insert which uses NEWSEQUNETIALID() column default

拟墨画扇 提交于 2019-12-12 02:13:32

问题


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)
        (
                ServerEnvironmentName,
                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?


回答1:


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.




回答2:


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.




回答3:


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



来源:https://stackoverflow.com/questions/3887970/simplify-sql-insert-which-uses-newsequnetialid-column-default

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!