创建、生成和验证 SQL 数据库项目
在能够实现自动部署、运行测试或检测架构漂移之前,需要一种管道能够实际构建的内容。 这是一个 SQL 数据库项目。
了解 SQL 数据库项目
将 SQL 数据库项目视为文件形式的数据库。 每个表、存储过程、视图和函数都位于其自己的 .sql 文件中。 声明每个对象一次,当需要添加列或更改数据类型时,可以编辑该单个文件。
如果以前使用过迁移脚本,则差异很大。 迁移脚本是有序的。 你编写 ALTER 语句,希望它按正确顺序运行,并随着时间的推移累积一系列不断增长的更改。 SQL 数据库项目采用相反的方法:维护每个对象的所需结束状态,工具在部署时计算项目与目标数据库之间的差异。
生成项目时,输出是一个 .dacpac 文件,即整个数据库架构的编译模型。 发布该 .dacpac 以创建新数据库或更新现有数据库。 生成过程为 CI/CD 提供了两项重要内容:
- 验证:在部署任何内容之前,针对特定版本的 SQL 检查对象引用和 T-SQL 语法。
-
可部署工件:
.dacpac成为在管道中流向每个环境的单个包。
在原始项目和 SDK 样式项目之间进行选择
SQL 数据库项目有两种格式。
原始格式基于 MSBuild(.NET Framework)构建,在 Visual Studio 中随附 SQL Server Data Tools (SSDT)。
SDK 样式格式基于Microsoft.Build.Sql项目 SDK 构建,是 Visual Studio Code 的 SQL 数据库项目扩展使用的格式。
对于新项目,请使用 SDK 样式。 它带来了原始格式没有的功能:
- .NET 8+ 支持,因此你可以在 Windows、Linux 和 macOS 上构建跨平台。 在 CI 运行环境中,当执行器不是 Windows 计算机时,此支持很重要。
- 数据库引用的 NuGet 包引用 ,因此依赖项管理遵循与 .NET 生态系统的其余部分相同的模式。
-
.sql文件的默认通配模式。 将文件拖放到项目文件夹中,并自动包含在生成中。 不需要手动文件输入。
如果有现有的原始项目,可以通过修改 .sqlproj 文件将其转换为 SDK 样式。 转换项目前,请备份项目文件并从当前项目存档 .dacpac。 比较“before”和“after” .dacpac 以确认转换保留了所有内容。
注释
SDK 样式的 SQL 项目在 Visual Studio Code 和 Visual Studio 2022 预览版中正式发布。 Visual Studio 2026 仅支持原始 SQL 项目格式。
创建和填充项目
可以从 Visual Studio Code、Visual Studio 或命令行创建 SQL 数据库项目。 对于没有图形环境可用的 CI/CD 方案,命令行特别方便。
若要创建新的 SDK 样式项目,请执行以下作:
dotnet new sqlproj -n MyDatabaseProject
📝 这会生成一个 .sqlproj 采用 SDK 样式格式的文件。 在此处,可以通过将文件拖放 .sql 到项目文件夹中来添加数据库对象。 默认通配模式会自动获取它们。
例如,若要定义表,请创建 Tables/Customers.sql:
CREATE TABLE [dbo].[Customers]
(
[CustomerID] INT NOT NULL PRIMARY KEY,
[FirstName] NVARCHAR(50) NOT NULL,
[LastName] NVARCHAR(50) NOT NULL,
[Email] NVARCHAR(100) NULL
);
从现有数据库开始? 使用架构比较工具可将实时数据库与空项目进行比较并导入差异,因此无需手动重新创建每个对象。
生成并验证项目
构建是安全网发挥作用的环节。 生成过程会验证每个对象引用,并针对目标平台检查 T-SQL 语法。 如果视图引用不存在的列,则生成将失败。 如果使用在 SQL Server 2025 中添加的向量函数,但项目面向 SQL Server 2017(Sql140),则编译过程会检测到该问题。
通过命令行构建:
dotnet build MyDatabaseProject.sqlproj
📝 默认情况下,在 bin/Debug 文件夹中生成一个 .dacpac 文件。
生成输出包括 错误 (阻止生成)和 警告 (如对象名称中的不一致大小写)。 警告不会停止构建,但值得关注。 你还可以启用 SQL 代码分析规则,在构建期间标记违反最佳做法的情况,捕获诸如已弃用的连接语法、视图中的 SELECT * 或 IN 谓词中未索引的列等问题。
目标平台在 .sqlproj 文件中设置,并控制哪些 T-SQL 功能通过验证。 将其设置为匹配部署目标,无论是 SQL Server 2025 还是 Azure SQL 数据库。
部署项目
当您拥有.dacpac后,SqlPackage 将处理部署。 将其安装为 .NET 全局工具:
dotnet tool install --global microsoft.sqlpackage
然后发布到目标数据库:
sqlpackage /Action:Publish /SourceFile:bin/Debug/MyDatabaseProject.dacpac /TargetConnectionString:"Server=myserver.database.windows.net;Database=mydb;Authentication=Active Directory Default"
📝 SqlPackage 是跨平台的,在 Windows、Linux 和 macOS 上运行。
部署期间发生的情况取决于目标。 对于 新数据库,SqlPackage 将导航对象依赖项图,并按正确的顺序创建每个对象,例如外键之前的引用表。 对于 现有数据库,它会计算与实时架构之间的 .dacpac 差异,然后只 ALTER 生成缩小差距所需的语句。 缺少两列? 两次添加操作会生成一个 ALTER TABLE。 该过程是幂等的。 部署相同的 .dacpac 五次,第五次运行不会更改。 升级多个租户时,也可以将单个 .dacpac 分散到一组数据库中。
在直接部署之前,可以预览计划的更改:
sqlpackage /Action:Script /SourceFile:bin/Debug/MyDatabaseProject.dacpac /TargetConnectionString:"..." /OutputPath:deploy-script.sql
sqlpackage /Action:DeployReport /SourceFile:bin/Debug/MyDatabaseProject.dacpac /TargetConnectionString:"..." /OutputPath:report.xml
Script 操作会生成将要运行的确切 T-SQL。 该DeployReport操作将生成每个CREATE、ALTER和DROP的XML摘要。 将更改推送到生产环境之前,请查看其中任意一个。
关键结论
SQL 数据库项目将每个数据库对象存储为声明性 .sql 文件,构建过程会将它们编译为单个 .dacpac 项目。 SDK 样式项目 (Microsoft.Build.Sql) 支持 .NET 8+、跨平台构建、NuGet 包引用以及 .sql 文件的默认通配模式。 生成过程会在任何内容到达数据库之前针对目标平台验证对象引用和 T-SQL 语法。 SqlPackage 计算 .dacpac 与目标数据库之间的差异,仅生成缩小差距所需的语句。 在部署到生产环境之前,使用Script和DeployReport操作来预览计划的更改。 SQL 数据库项目及其 .dacpac 项目和 SqlPackage 构成了未来所有内容的基础,包括源代码管理、CI/CD 管道、架构偏移检测和测试。