如何强制 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 语句而不是创建临时表?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Microsoft Office 12.0 Access Database Engine OLEDB Provider 访问 Excel 文件

如果不存在,则强制 mysqldump 使用 CREATE DATABASE

Microsoft JET Database Engine 错误 '80040e14'

安装Access Database Engine后,提示未注册Microsoft.ACE.OLEDB.12.0

### Error updating database. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 必须声明标量变量 "

如何为SQL Server2008添加登录账户并配置权限