SQL72007:在批处理中出现语法检查失败,附近出现“意外的文件末尾。”

16
在SSDT项目中(使用VS2017 / VS2015,SSDT版本15.1.61702.140),我无法使我的项目构建。编译器一直抱怨我的PostDeploymentScript中的SQL语句(是的,我已将BuildAction属性设置为PostDeploy)。这个SQL语句是:
if ('$(env)' = 'dvp')    
BEGIN
    PRINT 'creating users for dvp'
    :r .\SecurityAdditions\usersdvp.sql 
END
ELSE IF ('$(env)' = 'qat')
BEGIN
    PRINT 'creating users for qat'
    :r .\SecurityAdditions\usersqat.sql
END 

实际错误信息是:

D:\My\File\Path\PostDeploymentScript.sql (lineNum, col): Error: SQL72007:
The syntax check failed 'Unexpected end of file occurred.' in the batch near:

错误消息中最后一行(end)提到的行号。有任何想法是什么导致了这个错误?

5个回答

21

显然,问题是由我在引用的文件中使用的GO语句引起的。在if else块内部包含GO语句是无效的。这篇文章解释了这一点。我通过从引用的文件中移除所有GO语句,并将if else拆分成两个if,解决了这个问题。

IF ('$(env)' = 'dvp')
BEGIN 
    :R .\SecurityAdditions\UsersDVP.sql
END

IF ('$(env)' = 'qat')
BEGIN
    :R .\SecurityAdditions\UsersQAT.sql
END
GO 

1
如果在UsersDVP.sql脚本中有一个GO,则无法运行。 - Vinicius Gonçalves

7

我曾经遇到过同样的错误,因为我忘记在发布后脚本中包含的一个脚本结尾处添加GO语句。这使得修复变得困难,因为错误会指向下一个脚本中的第一行,而不是缺少GO语句的脚本。


1
我在尝试创建SQL数据库项目中的数据库用户时遇到了这个问题。将构建操作设置为“无”是没有用的,因为在部署期间脚本不会运行。
我使用类似以下脚本来创建用户:
IF NOT EXISTS (SELECT * FROM sys.sysusers WHERE name='$(DbUserName)')
    BEGIN
        CREATE USER [$(DbUserName)] WITH PASSWORD = '$(DbPassword)';
        ALTER ROLE [db_owner] ADD MEMBER [$(DbUserName)];
    END

我在项目文件中设置了两个SQLCMD变量,为其中一个设置默认值实际上解决了这个问题。这真的很奇怪,但我希望有一天能帮助某些可怜的人 :)


0

这种情况发生的另一个原因是,如果一个发布后脚本有一个BEGIN语句而没有相应的END行。在这种情况下,任何后续脚本中的GO都会导致此错误。当我编辑一个发布后脚本时,由于自己的粗心大意,我偶然发现了这个问题。


0

我想在这里分享我的经验。

我在构建我的SQL项目时遇到了相同的错误,但情况有所不同且棘手。

我在数据库表中引入了新列,并需要为该表中已存在的行填充该列。因此,基本上应该是一次性过程,因此我决定创建发布后脚本来完成这项工作。这个发布后脚本

  1. 以IF条件开始,以确保它仅针对给定数据库运行一次。 请注意,这不允许使用GO语句。
  2. 然后创建函数以创建临时函数。 这需要在Create Function之前使用GO语句,主要是因为它会更改数据库架构。 这很棘手,因为IF不允许使用GO语句。
  3. 然后使用临时函数的Update查询来实现我的要求。这没有GO语句也可以。
  4. 然后删除函数以删除临时函数。这也是数据库架构更改,理想情况下需要GO语句。

为了处理这种情况而不使用任何GO语句

  1. 我创建了一个变量,比如说 '@CreateFuntion NAVARCHAR(MAX)',并将其设置为整个创建函数语句。
  2. 使用 "EXEC sp_executesql @CreateFunction" 执行 Create Function。这会在单独的批处理中运行 Create Function。我原本以为 Drop Function 需要相同的处理方式,但在我的情况下,它可以在没有 GO 和 "EXEC sp_executesql" 的情况下工作,可能是因为它是脚本中的最后一条语句,并且无论如何都会在下一批处理中运行。
  3. 其他所有内容保持不变

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接