在提供或不提供 PK 时使 SQL 插入工作

发布于 2024-09-26 20:13:39 字数 1371 浏览 5 评论 0原文

我有以下存储过程:

ALTER 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)

    -- 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
    )

    -- If @ServerEnvironmentId was not supplied.
    IF (@ServerEnvironmentId IS NULL)
    BEGIN
        -- Get the ServerEnvironmentId.
        SELECT @ServerEnvironmentId = ServerEnvironmentId
        FROM @APPL_ServerEnvironment
    END

ServerEnvironmentId 列是一个主键,其上设置了默认值,即 (newsequentialid())。

我需要此存储过程适用于 2 个场景:

  1. 提供的值ServerEnvironmentId - 有效。
  2. 未为 ServerEnvironmentId 提供值 - 不起作用 - 无法插入空值。我认为通过在此列上设置默认值就可以了。

请有人帮助修改此程序,以便它适用于这两种情况。解决方案需要进行最小的更改,因为所有 SP 目前都遵循这一趋势。

I have the following stored procedure:

ALTER 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)

    -- 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
    )

    -- If @ServerEnvironmentId was not supplied.
    IF (@ServerEnvironmentId IS NULL)
    BEGIN
        -- Get the ServerEnvironmentId.
        SELECT @ServerEnvironmentId = ServerEnvironmentId
        FROM @APPL_ServerEnvironment
    END

The ServerEnvironmentId column is a primary key with a default set on it, which is (newsequentialid()).

I need this stored procedure to work for 2 scenarios:

  1. Value supplied for ServerEnvironmentId - WORKS.
  2. Value not supplied for ServerEnvironmentId - DOES NOT WORK - CANNOT INSERT NULL VALUE. I thought by setting a default on this column this would be fine.

Someone please help to ammend this procedure so that it may work for both scenarios. Solution needs to have minimal changes as all sp's currently following this trend.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

音盲 2024-10-03 20:13:39

如果列未包含在 INSERT 列表中,则默认值仅应用于插入。我建议进行以下不完全微不足道的更改(我已注释掉要删除的行):

ALTER 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 @ServerEnvironmentName is null
        SET @ServerEnvironmentName = newid()

    -- 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 
    ) 

    ---- If @ServerEnvironmentId was not supplied. 
    --IF (@ServerEnvironmentId IS NULL) 
    --BEGIN 
    --    -- Get the ServerEnvironmentId. 
    --    SELECT @ServerEnvironmentId = ServerEnvironmentId 
    --    FROM @APPL_ServerEnvironment 
    --END

此过程不会使用默认约束,但如果存在其他可能存在行的位置,则可以将其保留在适当的位置添加到表中。

Default values are only applied on inserts if the column is not included in the INSERT list. I'd recommend the following not entirely trivial change (I've commented out the lines to be removed):

ALTER 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 @ServerEnvironmentName is null
        SET @ServerEnvironmentName = newid()

    -- 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 
    ) 

    ---- If @ServerEnvironmentId was not supplied. 
    --IF (@ServerEnvironmentId IS NULL) 
    --BEGIN 
    --    -- Get the ServerEnvironmentId. 
    --    SELECT @ServerEnvironmentId = ServerEnvironmentId 
    --    FROM @APPL_ServerEnvironment 
    --END

The default constraint will not be used by this procedure, but you can leave it in place if there are other places where rows may be added to the table.

猫烠⑼条掵仅有一顆心 2024-10-03 20:13:39

(我的第一个答案很长,所以这是这个,所以我发布了第二个答案。)

我错过了您正在使用 NewSequentialId。同样,如果在 insert 语句中指定了列,则不会使用分配给该列的任何 DEFAULT 值 [除非您在 INSERT 语句中使用 DEFAULT 关键字,但这仍然是全部或全部 - 您不能说“如果@Var为空则默认”]。我认为您陷入了简单的分支和半冗余代码,大致如下:(

ALTER 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 is null
     BEGIN
        --  ServerEnvironmentId not provided by user, generate during the insert
        INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX) 
        ( 
            ServerEnvironmentName, 
            ServerEnvironmentDescription, 
            DateCreated, 
            UserCreatedId 
        ) 
        OUTPUT Inserted.ServerEnvironmentId INTO @APPL_ServerEnvironment 
        VALUES 
        ( 
            @ServerEnvironmentName, 
            @ServerEnvironmentDescription, 
            GETDATE(), 
            @UserCreatedId 
        ) 

        -- Get the new ServerEnvironmentId
        SELECT @ServerEnvironmentId = ServerEnvironmentId 
        FROM @APPL_ServerEnvironment 
     END 

    ELSE
     BEGIN
        --  ServerEnvironmentId is provided by user
        INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX) 
        ( 
            ServerEnvironmentName, 
            ServerEnvironmentDescription, 
            DateCreated, 
            UserCreatedId,
            ServerEnvironmentId
        ) 
        OUTPUT Inserted.ServerEnvironmentId INTO @APPL_ServerEnvironment 
        VALUES 
        ( 
            @ServerEnvironmentName, 
            @ServerEnvironmentDescription, 
            GETDATE(), 
            @UserCreatedId,
            @ServerEnvironmentId
        ) 
     END

为什么在插入期间锁定整个表?)

(My first answer was long and so it this one, so I'm posting a second answer.)

I missed that you were using NewSequentialId. Again, if a column is specified within the insert statement, any DEFAULT values assigned to that column will not be used [unless you use the DEFAULT keyword in the INSERT statement, but that's still all or nothing--you can't say "if @Var is null then DEFAULT"]. I think you are stuck with simple branching and semi-redundant code, along the lines of:

ALTER 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 is null
     BEGIN
        --  ServerEnvironmentId not provided by user, generate during the insert
        INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX) 
        ( 
            ServerEnvironmentName, 
            ServerEnvironmentDescription, 
            DateCreated, 
            UserCreatedId 
        ) 
        OUTPUT Inserted.ServerEnvironmentId INTO @APPL_ServerEnvironment 
        VALUES 
        ( 
            @ServerEnvironmentName, 
            @ServerEnvironmentDescription, 
            GETDATE(), 
            @UserCreatedId 
        ) 

        -- Get the new ServerEnvironmentId
        SELECT @ServerEnvironmentId = ServerEnvironmentId 
        FROM @APPL_ServerEnvironment 
     END 

    ELSE
     BEGIN
        --  ServerEnvironmentId is provided by user
        INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX) 
        ( 
            ServerEnvironmentName, 
            ServerEnvironmentDescription, 
            DateCreated, 
            UserCreatedId,
            ServerEnvironmentId
        ) 
        OUTPUT Inserted.ServerEnvironmentId INTO @APPL_ServerEnvironment 
        VALUES 
        ( 
            @ServerEnvironmentName, 
            @ServerEnvironmentDescription, 
            GETDATE(), 
            @UserCreatedId,
            @ServerEnvironmentId
        ) 
     END

(Why lock the entire table during the insert?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文