SQL Visual Studio 中的服务器数据库项目 - 如何构建新数据库
SQL Server Database Project in Visual Studio - how to structure for new database
我想创建一个 SQL 服务器数据库项目,用于创建新数据库。这是我的项目的结构:
SQL Server Database Project Structure
基本上,我想要 4 个表,所以我为它们添加了 4 个 .sql
脚本。
CREATE TABLE [dbo].[MovieActors]
(
[Id] INT NOT NULL PRIMARY KEY,
[ActorID] INT NOT NULL,
[MovieID] INT NOT NULL
)
CREATE TABLE [dbo].[Actors]
(
[Id] INT NOT NULL PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL,
[Bio] NVARCHAR(MAX) NULL,
[Sex] NCHAR(10) NOT NULL,
[DOB] DATE NULL
)
CREATE TABLE [dbo].[Movies]
(
[Id] INT NOT NULL PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL,
[Year of Release] SMALLINT NULL,
[PLOT] NVARCHAR(MAX) NULL,
[Poster] NVARCHAR(MAX) NULL,
[ProducerId] int FOREIGN KEY REFERENCES Producers(Id)
)
CREATE TABLE [dbo].[Producers]
(
[Id] INT NOT NULL PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL,
[Bio] NVARCHAR(MAX) NULL,
[Sex] NCHAR(10) NULL,
[DOB] DATE NULL
)
而且我还添加了预部署(用于删除现有数据)和 post-部署脚本(用于播种初始数据)。
预部署:
DROP TABLE [dbo].MovieActors
DROP TABLE [dbo].Movies
DROP TABLE dbo.Actors
DROP TABLE dbo.Producers
Post-部署:
INSERT INTO dbo.Actors (Id, Name, Sex)
VALUES (1, 'Actor1', 'MALE')
INSERT INTO dbo.Producers (Id, Name, Sex)
VALUES (1, 'Producer1', 'MALE')
INSERT INTO dbo.Movies (Id, Name, ProducerId)
VALUES (1, 'Movie1', 1)
INSERT INTO dbo.MovieActors (Id, MovieID, ActorID)
VALUES (1, 1, 1)
- 但是每次我构建项目时它都没有部署 - 只显示构建成功
- 此外,数据库创建脚本在哪里。
- 当我右键单击发布并选择生成脚本选项时,主脚本中只有预部署脚本和 post 部署脚本。 -
Right Click Project -> Publish option
这是生成的脚本 -
/*
Deployment script for MoviesDatabase
This code was generated by a tool.
Changes to this file may cause incorrect behavior and will be lost if
the code is regenerated.
*/
GO
SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON;
SET NUMERIC_ROUNDABORT OFF;
GO
:setvar DatabaseName "MoviesDatabase"
:setvar DefaultFilePrefix "MoviesDatabase"
:setvar DefaultDataPath "C:\Users\viiye\AppData\Local\Microsoft\VisualStudio\SSDT"
:setvar DefaultLogPath "C:\Users\viiye\AppData\Local\Microsoft\VisualStudio\SSDT"
GO
:on error exit
GO
/*
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported.
To re-enable the script after enabling SQLCMD mode, execute the following:
SET NOEXEC OFF;
*/
:setvar __IsSqlCmdEnabled "True"
GO
IF N'$(__IsSqlCmdEnabled)' NOT LIKE N'True'
BEGIN
PRINT N'SQLCMD mode must be enabled to successfully execute this script.';
SET NOEXEC ON;
END
GO
USE [$(DatabaseName)];
GO
/*
Pre-Deployment Script Template
--------------------------------------------------------------------------------------
This file contains SQL statements that will be executed before the build script.
Use SQLCMD syntax to include a file in the pre-deployment script.
Example: :r .\myfile.sql
Use SQLCMD syntax to reference a variable in the pre-deployment script.
Example: :setvar TableName MyTable
SELECT * FROM [$(TableName)]
--------------------------------------------------------------------------------------
*/
Drop table [dbo].MovieActors
Drop table [dbo].Movies
Drop table dbo.Actors
Drop table dbo.Producers
GO
GO
/*
Post-Deployment Script Template
--------------------------------------------------------------------------------------
This file contains SQL statements that will be appended to the build script.
Use SQLCMD syntax to include a file in the post-deployment script.
Example: :r .\myfile.sql
Use SQLCMD syntax to reference a variable in the post-deployment script.
Example: :setvar TableName MyTable
SELECT * FROM [$(TableName)]
--------------------------------------------------------------------------------------
*/
INSERT INTO dbo.Actors (Id,Name,Sex)
values (1,'Actor1','MALE')
INSERT INTO dbo.Producers (Id,Name,Sex)
values (1,'Producer1','MALE')
INSERT INTO dbo.Movies (Id,Name,ProducerId)
values (1,'Movie1',1)
Insert into dbo.MovieActors (Id,MovieID,ActorID)
values (1,1,1)
GO
GO
PRINT N'Update complete.';
GO
可以看出,这个用于发布的脚本中没有创建表脚本。为什么?这是满足我需要从头开始创建表的要求的正确方法吗?
这是发布项目的简化步骤:
- 项目已构建且 DACPAC 文件是此步骤的输出
- DACPAC 与目标数据库进行比较并生成发布脚本
- 针对目标数据库执行发布脚本
您遇到的问题是,在执行第 2 步时,目标数据库中存在 table,因此它们的创建未包含在发布脚本中。预部署脚本在第 3 步执行!
基本上你需要做的就是不要丢弃 tables。只需在预脚本中截断它们并填充 post。或者简单地在 post 脚本中使用 MERGE 语句。您可以使用 generate-sql-merge 过程为所需的 table.
生成 MERGE 语句
我想创建一个 SQL 服务器数据库项目,用于创建新数据库。这是我的项目的结构:
SQL Server Database Project Structure
基本上,我想要 4 个表,所以我为它们添加了 4 个 .sql
脚本。
CREATE TABLE [dbo].[MovieActors]
(
[Id] INT NOT NULL PRIMARY KEY,
[ActorID] INT NOT NULL,
[MovieID] INT NOT NULL
)
CREATE TABLE [dbo].[Actors]
(
[Id] INT NOT NULL PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL,
[Bio] NVARCHAR(MAX) NULL,
[Sex] NCHAR(10) NOT NULL,
[DOB] DATE NULL
)
CREATE TABLE [dbo].[Movies]
(
[Id] INT NOT NULL PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL,
[Year of Release] SMALLINT NULL,
[PLOT] NVARCHAR(MAX) NULL,
[Poster] NVARCHAR(MAX) NULL,
[ProducerId] int FOREIGN KEY REFERENCES Producers(Id)
)
CREATE TABLE [dbo].[Producers]
(
[Id] INT NOT NULL PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL,
[Bio] NVARCHAR(MAX) NULL,
[Sex] NCHAR(10) NULL,
[DOB] DATE NULL
)
而且我还添加了预部署(用于删除现有数据)和 post-部署脚本(用于播种初始数据)。
预部署:
DROP TABLE [dbo].MovieActors
DROP TABLE [dbo].Movies
DROP TABLE dbo.Actors
DROP TABLE dbo.Producers
Post-部署:
INSERT INTO dbo.Actors (Id, Name, Sex)
VALUES (1, 'Actor1', 'MALE')
INSERT INTO dbo.Producers (Id, Name, Sex)
VALUES (1, 'Producer1', 'MALE')
INSERT INTO dbo.Movies (Id, Name, ProducerId)
VALUES (1, 'Movie1', 1)
INSERT INTO dbo.MovieActors (Id, MovieID, ActorID)
VALUES (1, 1, 1)
- 但是每次我构建项目时它都没有部署 - 只显示构建成功
- 此外,数据库创建脚本在哪里。
- 当我右键单击发布并选择生成脚本选项时,主脚本中只有预部署脚本和 post 部署脚本。 -
Right Click Project -> Publish option
这是生成的脚本 -
/*
Deployment script for MoviesDatabase
This code was generated by a tool.
Changes to this file may cause incorrect behavior and will be lost if
the code is regenerated.
*/
GO
SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON;
SET NUMERIC_ROUNDABORT OFF;
GO
:setvar DatabaseName "MoviesDatabase"
:setvar DefaultFilePrefix "MoviesDatabase"
:setvar DefaultDataPath "C:\Users\viiye\AppData\Local\Microsoft\VisualStudio\SSDT"
:setvar DefaultLogPath "C:\Users\viiye\AppData\Local\Microsoft\VisualStudio\SSDT"
GO
:on error exit
GO
/*
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported.
To re-enable the script after enabling SQLCMD mode, execute the following:
SET NOEXEC OFF;
*/
:setvar __IsSqlCmdEnabled "True"
GO
IF N'$(__IsSqlCmdEnabled)' NOT LIKE N'True'
BEGIN
PRINT N'SQLCMD mode must be enabled to successfully execute this script.';
SET NOEXEC ON;
END
GO
USE [$(DatabaseName)];
GO
/*
Pre-Deployment Script Template
--------------------------------------------------------------------------------------
This file contains SQL statements that will be executed before the build script.
Use SQLCMD syntax to include a file in the pre-deployment script.
Example: :r .\myfile.sql
Use SQLCMD syntax to reference a variable in the pre-deployment script.
Example: :setvar TableName MyTable
SELECT * FROM [$(TableName)]
--------------------------------------------------------------------------------------
*/
Drop table [dbo].MovieActors
Drop table [dbo].Movies
Drop table dbo.Actors
Drop table dbo.Producers
GO
GO
/*
Post-Deployment Script Template
--------------------------------------------------------------------------------------
This file contains SQL statements that will be appended to the build script.
Use SQLCMD syntax to include a file in the post-deployment script.
Example: :r .\myfile.sql
Use SQLCMD syntax to reference a variable in the post-deployment script.
Example: :setvar TableName MyTable
SELECT * FROM [$(TableName)]
--------------------------------------------------------------------------------------
*/
INSERT INTO dbo.Actors (Id,Name,Sex)
values (1,'Actor1','MALE')
INSERT INTO dbo.Producers (Id,Name,Sex)
values (1,'Producer1','MALE')
INSERT INTO dbo.Movies (Id,Name,ProducerId)
values (1,'Movie1',1)
Insert into dbo.MovieActors (Id,MovieID,ActorID)
values (1,1,1)
GO
GO
PRINT N'Update complete.';
GO
可以看出,这个用于发布的脚本中没有创建表脚本。为什么?这是满足我需要从头开始创建表的要求的正确方法吗?
这是发布项目的简化步骤:
- 项目已构建且 DACPAC 文件是此步骤的输出
- DACPAC 与目标数据库进行比较并生成发布脚本
- 针对目标数据库执行发布脚本
您遇到的问题是,在执行第 2 步时,目标数据库中存在 table,因此它们的创建未包含在发布脚本中。预部署脚本在第 3 步执行!
基本上你需要做的就是不要丢弃 tables。只需在预脚本中截断它们并填充 post。或者简单地在 post 脚本中使用 MERGE 语句。您可以使用 generate-sql-merge 过程为所需的 table.
生成 MERGE 语句