作为我正在工作的公司的一部分,我现在需要创建一些数据库升级脚本来替换以前承包商的某些工作。
运行以下块之前的代码,创建新的ID列,然后此脚本将查找以填充值,然后删除一些列。
IF EXISTS (
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID(N'[Central].[Core.Report].[ReportLessonComp]')
AND name = 'Name')
and
EXISTS (
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID(N'[Central].[Core.Report].[ReportLessonComp]')
AND name = 'Code')
BEGIN
UPDATE
[Central].[Core.Report].[ReportLessonComp]
SET
CompetencyId = rc.Id
FROM
[Central].[Core.Report].[ReportLessonComp] rlc
INNER JOIN
[Core.Lookup].ReportCompetency rc
ON
rc.Code = rlc.Code and rc.Name = rlc.Name
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN CODE
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN [Name]
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN [Description]
END
GO
在运行if exist \不存在检查时,然后选择getdate(),可以正常运行,并得到我期望的结果。
但是,当我运行上面的代码块时,我得到了错误
第207级16州立23行
无效的列名“代码”。
第207级16州立23行
无效的列名“名称”。
此脚本是较大的升级脚本的一部分,并在系统调用RoundHouse https://github.com/chucknorris/roundhouse(该公司选择的系统)中使用。
在上述条件之前(如果存在),
IF (SELECT COUNT(1) FROM sys.columns
WHERE OBJECT_ID = OBJECT_ID('[Central].[Core.Report].[ReportLessonComp]')
AND Name in ('Name','Code')) = 2
也给出了同样的问题。我有五个表需要更新,如果我下一个PR无法解决此问题,这将阻止团队工作。
我该怎么办才能阻止升级脚本失败?
编辑-我在varchar字段上进行链接的原因还在于,以前的开发人员未在表之间创建关系,而只是在表中插入字符串而不是通过ID进行关联,从而可能导致未链接的\不一致的数据。
在此之前的表编辑将创建新的id列,并且此脚本正在获取值并删除不再需要的列
答案 0 :(得分:1)
SQL Server将在执行之前解析整个语句,因此存在检查并不能保护您免受正在解析的更新的影响。如果该列已被删除,则该语句无效,并且您将收到解析错误。 update语句必须作为动态SQL执行,基本上是sp_execute,以便不直接解析更新的varchar。
对于SQL Server 2016及更高版本,drop列也可以得到更多保护:
zip = zipfile.ZipFile(open(r'c:\temp\test.zip', 'rb'))
file = zip.open('test.xlsx', 'r')
data = file.read()
if zipfile.is_zipfile(StringIO.StringIO(data)):
print('Zip')
else:
print('Not zip')