2013-05-11 2 views
2

.dacpacs를 사용하여 다양한 환경에 데이터베이스 업데이트를 배포했습니다. 특정 업데이트의 게시가 실패하게되는 시나리오를 발견했습니다.SSDT 게시 (.dacpac)를 사용하여 null이 아닌 외래 키 스키마 업데이트를 배포합니다.

새 테이블 dbo.Supplier을 추가하고 새 테이블을 참조하는 nullable foriegn 키가있는 다른 테이블 dbo.PickZone에 열을 추가해야합니다. SSDT 프로젝트 내의 스키마는이를 반영하고 새로운 NOT NULL 열을 준비하기 위해 다음과 같은 사전 배포 스크립트를 가지고 있습니다.

IF object_id('dbo.Supplier') IS NULL 
BEGIN 
    CREATE TABLE [dbo].[Supplier] 
    (
     [SupplierId] INT IDENTITY(1,1) NOT NULL, 
     [Name] varchar(50) NOT NULL, 
     CONSTRAINT [PK_Supplier] PRIMARY KEY CLUSTERED ([SupplierId]) 
    ); 

    SET IDENTITY_INSERT [dbo].[Supplier] ON; 
    INSERT INTO Supplier (SupplierId, Name) VALUES (1, 'Default Supplier') 
    SET IDENTITY_INSERT [dbo].[Supplier] OFF; 

    ALTER TABLE dbo.PickZone ADD SupplierId int NULL; 

    UPDATE PickZone SET SupplierId = 1 

END 

업데이트 스키마 및 데이터 위의 스크립트를 게시 할 때 그것을 dbo.PickZone.SupplierId에 foriegn 키 제약 조건을 적용 할 때 실패하지 않습니다 (내가 sqlpackage.exe을 사용하고 있습니다)가 발생되도록 :

CREATE TABLE [dbo].[PickZone] 
(
    [PickZoneId] INT IDENTITY (1, 1) NOT NULL PRIMARY KEY, 
    [Name] VARCHAR(50) NOT NULL, 
    [SupplierId] INT NOT NULL, 
    CONSTRAINT [FK_PickZone_Supplier] FOREIGN KEY ([SupplierId]) REFERENCES [dbo].[Supplier] ([SupplierId]) 
) 

문제는 vs2012 Publish와 sqlpackage.exe 배포가 모두 필요한 스키마 업데이트를 준비한 다음 배포 전 스크립트를 실행 한 다음 스키마 업데이트를 실행한다는 것입니다. 스키마 업데이트는 사전 배포 스크립트로 인해 동기화되지 않았습니다 스키마 변경.

이로 인해 스키마 게시가 다시 테이블 및 열을 추가하려고 시도하고 실패하게됩니다.

이 에게

사람이 알고 있나요 ... 나는 분명히 dacpac의 배포의 외부 준비 스크립트의이 유형을 실행하는 내 배포 프로세스를 변경할 수 있지만, 나는 이러한 종류의 dacpac처럼 모든 스키마 변경에 대한 책임을 질 것입니다 dacpac이 이러한 유형의 업데이트를 제공하도록 게시하는 방법?

답변

1

나는 이것을 잘못된 순서로 시도한다고 생각합니다. 기본적으로 SSDT는 전체 업데이트가 완료 될 때까지 (배포 후 스크립트 이후에도) 제약 조건을 검사하지 않습니다. 즉, 기본 및 제약 조건을 사용하여 프로젝트에 테이블을 추가하고 사후 배포 스크립트에서 데이터 삽입/업데이트를 실행하고 모든 작업이 완료된 후 SSDT에서 FK 제약 조건을 활성화 할 수 있어야합니다. 스크립트를

  • 스냅 샷을-배포 후

    • 이 테이블을 채우기 테이블
    • 만들기 스키마
    • : 당신이 편안하지 않은 경우

      , 당신은 항상이 순서대로 작업을 수행 할 수 있습니다

    • -----------------
    • 열을 추가 (기본값)와 FK 제약
    • 스냅 샷 스키마
    • ,
    • -----------------
    • 스냅 샷 A는
    • 스냅 샷 B 게시 게시

    나는 두 번째 과정을 통해 갈 필요가 있다고 생각하지 않습니다 대부분의 경우 옵션이 다른 모든 것 다음에 제약 조건을 검사 할 수 있도록 올바르게 설정되어있는 경우.

  • +0

    감사를, 내가주지 사후 배치 후 삽입/업데이트를 실행합니다. 이 (오래된) 스레드의 끝 부분에서는 작동하지 않는다고 기록되어 있지만 http://social.msdn.microsoft.com/Forums/en-US/ssdt/thread/05e195cb-2005-4dcf-84db-705b22972dc8 –

    +0

    If 이것은 드물기 때문에 스크립트를 생성하고 편집하는 것이 좋습니다. 그러나, 나는 당신이 프로젝트를 통해 이것을 설정할 수 있도록 허용되지 않는 FK 제약 조건을 가진 똑똑한 기본값 (또는 실제 기본값)의 조합을 사용할 수 있어야한다고 생각한다. 스레드는 상호 의존적 인 여러 변경 사항을 가리키는 것처럼 보였습니다. "새 제약에 대한 스크립트 유효성 검사"옵션이 도움이됩니다. 방금 AW2012라는 빠른 검사를 수행하고 NOCHECK FK를 작성한 후 배치 후 스크립트를 점검 한 다음 변경했습니다. –

    +0

    나는 똑같은 문제가 있었고이 솔루션은 나를 위해 일했다. sqlpackage.exe/action : script .....를 호출하면 실행될 스크립트를 볼 수 있습니다. VS2013에서는 "nocheck와 함께"FK를 추가하여 배포 후 스크립트를 실행 한 다음 FK를 변경하지만 Peter에 의해 표시된대로 "WITH CHECK"를 변경합니다 –

    2

    나는 나의 해결책을 설명 할 것이다. dacpac을 배치하는 sqlpackage 툴을 사용하려고합니다. 이 도구는 많은 매개 변수를 지원합니다. 그 중 하나가 GenerateSmartDefaults입니다. here을 참조하십시오.

    전 배포 전 스크립트에는 스키마 수정이 없어야한다고 생각합니다. SELECT, INSERT, UPDATE, DELETE 문만 가능합니다. 배포 후 스크립트.

    1. db 스키마를 수정하십시오 (기본값 또는 외래 키가 아닌 null 열을 추가하지 마십시오).
    2. 배포 후 스크립트에서이 열에 대해 UPDATE 문을 추가하고 dacpac을 빌드합니다.
    3. 배포 같은 SqlPackage 도구이 dacpac : sqlpackage.exe/작업 : /SourceFile:your.dacpac/TargetServerName 게시 : 서버/TargetDatabaseName을 : 여기서 databaseName/p는 : GenerateSmartDefaults은 = 사실