SQL代码评估停止有效的事务

时间:2019-05-07 12:35:58

标签: sql sql-server tsql

作为我正在工作的公司的一部分,我现在需要创建一些数据库升级脚本来替换以前承包商的某些工作。

运行以下块之前的代码,创建新的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列,并且此脚本正在获取值并删除不再需要的列

1 个答案:

答案 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')