sql-server - 由于缺少似乎存在的列,Visual Studio SQL Server 数据库未成功迁移
问题描述
几年前,我在 Visual Studio 中设置了一个项目以输出到 Azure SQL V12 数据库,并尝试sqlcmd
与迁移脚本一起使用(我这样说也是为了指出在某一时刻一切正常,下面讨论的所有内容已投入生产)。
我的部署后脚本如下所示:
PRINT N'Starting post deployment';
:setvar WorkDirectory "F:\path\to\scripts"
PRINT N'Starting 1.01';
:r $(WorkDirectory)\1.01\Deployment.sql
PRINT N'Starting 1.02';
:r $(WorkDirectory)\1.02\Deployment.sql
PRINT N'Starting 1.03'; :r $(WorkDirectory)\1.03\Deployment103.sql
PRINT N'Starting 1.04'; :r $(WorkDirectory)\1.04\Deployment104.sql
在没有对项目进行任何更改(无论如何都不是有意识的)之后,我发现当我尝试调试/生成数据库并应用迁移脚本时,我收到一个错误,因为引用了一个不存在的列桌子。以下是Deployment104.sql
文件中的违规部分:
IF NOT EXISTS (SELECT *
FROM sys.columns
WHERE Name = N'MissingColumn'
AND Object_ID = Object_ID(N'TableA'))
BEGIN
ALTER TABLE TableA
ADD MissingColumn INT NOT NULL
END
GO
IF NOT EXISTS (SELECT 1
FROM information_schema.Routines
WHERE ROUTINE_NAME = 'LIST_CODES'
AND ROUTINE_TYPE = 'PROCEDURE'
AND ROUTINE_SCHEMA = 'dbo' )
BEGIN;
EXEC('CREATE PROCEDURE dbo.LIST_CODES as set nocount on;')
END
GO
ALTER PROCEDURE [dbo].LIST_CODES
AS
SELECT *
FROM CodesTable ct
LEFT JOIN TableA ta ON ct.CodeId = ta.CodeId
WHERE ta.MissingColumn= 1999
ORDER BY ct.CodeId
GO
Db 最终在此时部分创建。但是,当我运行第一次检查该列是否存在时,我实际上得到了一个条目,这意味着该列确实存在于 TableA 中。然而我在服务器资源管理器(VS 2019 预览版 16.4)中看不到它,显然脚本的下一部分也看不到它。
我做错了什么,和/或如何使脚本和数据库就哪些列存在而哪些不存在达成一致?
编辑:作为更新,在运行 PostDeploymentScript 失败时,运行有问题的脚本本身(在本例中为 Deployment104)工作得很好,之后列和存储过程都完全按照服务器资源管理器中的预期显示,并且可以通过其他查询。
解决方案
我认为问题在于您正在尝试将非空列添加到现有表中。您需要添加一个默认值,例如 0 或使用支持 null 的数据类型。例如:
BEGIN
alter table TableA
ADD MissingColumn int NOT NULL DEFAULT 0
END
在第二个 BEGIN 之后还有一个分号。
当前的:
IF NOT EXISTS ( SELECT 1 FROM information_schema.Routines
WHERE ROUTINE_NAME = 'LIST_CODES'AND ROUTINE_TYPE = 'PROCEDURE' AND ROUTINE_SCHEMA = 'dbo' )
BEGIN;
EXEC('CREATE PROCEDURE dbo.LIST_CODES as set nocount on;')
END
GO
固定的:
IF NOT EXISTS ( SELECT 1 FROM information_schema.Routines
WHERE ROUTINE_NAME = 'LIST_CODES'AND ROUTINE_TYPE = 'PROCEDURE' AND ROUTINE_SCHEMA = 'dbo' )
BEGIN
EXEC('CREATE PROCEDURE dbo.LIST_CODES as set nocount on;')
END
GO
在这些更改之后,我能够让语句在 sqlfiddle 中运行。这是链接http://sqlfiddle.com/#!18/51253/3
推荐阅读
- communication - 标准软件模式的 Word
- android - AppCompatDialogFragment 更改背景颜色
- r - 在 For Loop R 中操作迭代的 CSV 文件
- node.js - 开始在 npm prestart 上运行 cron 作业
- python - 带有 Python 3 和 virtualenv 的 AWS Lambda 无法安装依赖项
- r - R中的ggplot2堆叠条形图
- sql - 优化 Spark 中的 Hive 表加载时间
- javascript - 使用 Javascript 将两个 SVG 元素合二为一?
- javascript - 为什么控制台将 HTML 元素显示为普通对象?
- javascript - backgroundColor 没有做任何事情?