如何强制 Microsoft Database Project 为主键约束生成 ALTER 语句而不是创建临时表?

Posted

技术标签:

【中文标题】如何强制 Microsoft Database Project 为主键约束生成 ALTER 语句而不是创建临时表?【英文标题】:How to force Microsoft Database Project generate ALTER statement for primary key constraint instead of creating temp table? 【发布时间】:2017-03-20 19:35:30 【问题描述】:

我有以下 LoginLogo 表的脚本:

CREATE TABLE [LoginLogo] (
    [LoginLogoId]           INT               IDENTITY (1, 1) NOT NULL,
    [LoginId]               INT               NOT NULL,
    [LogoNm]                NVARCHAR(255)     NULL,
    CONSTRAINT [PK_LoginLogo_LoginLogoId] PRIMARY KEY CLUSTERED ([LoginId] ASC),
    CONSTRAINT [FK_LoginLogo_LoginId] FOREIGN KEY ([LoginId]) 
    REFERENCES [Login] ([LoginId])
);

GO
CREATE NONCLUSTERED INDEX [IF_LoginLogo_LoginId]
    ON [LoginLogo]([LoginId] ASC)
    ON [INDX];

我需要更改主键约束,所以我只更改了一行,请看下面的更改:

CONSTRAINT [PK_LoginLogo_LoginLogoId] PRIMARY KEY CLUSTERED ([LoginLogoId] ASC),

数据库项目完美构建更改的代码,但是当它生成数据库更新语句时,它会生成临时表而不是简单的 ALTER 语句。请参阅下面生成的脚本:

CREATE TABLE [tmp_ms_xx_LoginLogo] (
    [LoginLogoId]        INT            IDENTITY (1, 1) NOT NULL,
    [LoginId]            INT            NOT NULL,
    [LogoNm]             NVARCHAR (255) NULL,
    CONSTRAINT [tmp_ms_xx_constraint_PK_LoginLogo_LoginLogoId1] 
    PRIMARY KEY CLUSTERED ([LoginLogoId] ASC)
);

IF EXISTS (SELECT TOP 1 1 
           FROM   [apps].[LoginLogo])
    BEGIN
        SET IDENTITY_INSERT [apps].[tmp_ms_xx_LoginLogo] ON;
        INSERT INTO [apps].[tmp_ms_xx_LoginLogo] ([LoginLogoId], [LoginId], [LogoNm])
        SELECT   [LoginLogoId],
                 [LoginId],
                 [LogoNm],
        FROM     [LoginLogo]
        ORDER BY [LoginLogoId] ASC;
        SET IDENTITY_INSERT [tmp_ms_xx_LoginLogo] OFF;
    END

DROP TABLE [LoginLogo];

EXECUTE sp_rename N'[tmp_ms_xx_LoginLogo]', N'LoginLogo';

EXECUTE sp_rename N'[tmp_ms_xx_constraint_PK_LoginLogo_LoginLogoId1]',
N'PK_LoginLogo_LoginLogoId', N'OBJECT';

是否可以告诉数据库项目生成 ALTER 语句而不是创建临时表?如何强制 Microsoft Database Project 执行此操作?

【问题讨论】:

【参考方案1】:

请记住,如果您更改表的聚集索引,则该表将被重建无论脚本是使用 ALTER TABLE 还是 SSDT 生成的带有临时表的东西,通常解决这些问题的方法是提前做ALTER

意思是,您需要一个脚本,通常称为预部署脚本(预部署不起作用,因为它是在比较后运行的),它会进行昂贵的更改,以便在比较时运行更改已经发生,因此不会被 dacpac 部署重复。

在您执行任何sqlpackage 操作之前,该脚本需要作为部署的一部分运行。您可以在此脚本中将更改指定为alter table

在这种特殊情况下,无论哪种方式都将重建表,我看不出它对整体部署时间有很大影响。

【讨论】:

以上是关于如何强制 Microsoft Database Project 为主键约束生成 ALTER 语句而不是创建临时表?的主要内容,如果未能解决你的问题,请参考以下文章