ssdt:更改主键/辅助键的类型

时间:2016-09-16 06:33:06

标签: sql-server-data-tools dacpac

原始table1和Table2。两个表都有数据。

CREATE TABLE [dbo].[Table1]
(
    [Id] int NOT NULL PRIMARY KEY 
)
CREATE TABLE [dbo].[Table2]
(
    [Id] INT NOT NULL PRIMARY KEY, 
    [Table1Id] Int NULL,    

    Constraint [FK_Table1_Table2] foreign key ([Table1Id]) references [Table1] (Id)
)

我想将Table1.Id更改为UNIQUEIDENTIFIER

显然,只需跳转并将类型从int更改为UNIQUEIDENTIFIER Table1.Id和' Table2.Table1Id'。然后发布。这是代码:

CREATE TABLE [dbo].[tmp_ms_xx_Table1] (
    [Id] UNIQUEIDENTIFIER NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

IF EXISTS (SELECT TOP 1 1 
           FROM   [dbo].[Table1])
    BEGIN
        INSERT INTO [dbo].[tmp_ms_xx_Table1] ([Id])
        SELECT   [Id]
        FROM     [dbo].[Table1]
        ORDER BY [Id] ASC;
    END

此代码将失败,因为原始Table1.IdInt,而临时表ID为UNIQUEIDENTIFIER

然后,我尝试使用Pre-Scripts。理想情况下,所有更改都将手动完成。

--drop fk constraint
alter table [Table2] drop constraint [FK_Table1_Table2];

--rename table1.id
exec sp_rename 'Table1.Id', 'Id2', 'COLUMN';

alter table [Table1] add Id uniqueidentifier not null 
    default newid();

--rename table2.table1id
exec sp_rename 'Table2.Table1Id', 'Table1Id2', 'COLUMN';
alter table [Table2] add Table1Id uniqueidentifier null;


update t2 set t2.Table1ID = t1.Id
    from Table2 t2 left join Table1 t1 on t2.Table1Id2 = t1.Id2;

alter table [Table2] add constraint [FK_Table1_Table2] foreign key (Table1Id) references Table1 (Id);

然而它再次失败,因为SSDT正试图再次将其数据结构与目标数据库进行比较。

请问好吗?

2 个答案:

答案 0 :(得分:4)

你是对的。问题是您不能在预部署脚本中包含架构更改,因为SSDT的部署脚本是在架构更改之前生成的。因此,它仅对仅数据更改有用。

解决方案是在SSDT流程之外完成此操作。是的,这是一个预部署之前的脚本!基本上你必须在之前自己应用你的更改你甚至到达SSDT位。

(可能有一种方法可以通过自定义部署贡献者来实现。毕竟,代码中的所有内容都可以实现......)

我是否可以说服您查看基于迁移的解决方案,因为您似乎需要一个细粒度脚本“自定义”的元素。 DBUp是一种流行的开源解决方案。 ReadyRoll是一个更加集成的商业解决方案,与SSDT共享很多。

答案 1 :(得分:1)

问题是旧数据。没有第2步表格中的数据就可以了。

1. 预脚本:将旧数据复制/处理到临时表,从原始表中删除

create table #table1 (
    id int null, 
    id2 uniqueidentifier null
);
insert into #table1 (id,id2) 
    select id,newid() from Table1;

create table #table2 (
    id int null, 
    table1id int null, 
    table1id2 uniqueidentifier null
);
insert into #table2 (id, table1id) 
    select id,table1id from Table2;

update t2 set t2.table1id2=t1.id2
    from #table2 t2 left join #table1 t1 on t2.table1id = t1.id;

delete from table2;
delete from table1;
  1. dacpac 会自动生成架构的更改。它会好的,因为不再存在任何数据。

  2. 后脚本:在预脚本中从临时表中插回数据:

    插入table1(id)     从#table1;

    中选择id2

    插入table2(id,table1id)     从#table2;

  3. 中选择id,table1id2