SQL72007: 句法检查失败 'Unexpected end of file occurred.' 批次附近 :

SQL72007: The syntax check failed 'Unexpected end of file occurred.' in batch near :

在 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:

最后一行(结束)的错误消息中引用的行号。知道是什么原因造成的吗?

显然问题出在我所引用的文件中的 GO 语句。在 if else 块中包含 GO 语句是无效的。 Here 是一篇对此进行解释的文章。我能够通过从引用文件中删除所有 GO 语句并将 if else 拆分为两个 if.

来使其工作
IF ('$(env)' = 'dvp')
BEGIN 
    :R .\SecurityAdditions\UsersDVP.sql
END

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

我遇到了同样的错误,因为我忘记使用 GO 语句结束 post 部署脚本中包含的脚本之一。难以修复的是错误将指向下一个脚本中的第一行,而不是 GO 语句丢失的脚本。

我 运行 在尝试在 SQL 数据库项目中创建数据库用户时遇到了这个问题。将构建操作设置为 None 没有用,因为这样您的脚本在部署期间不会 运行。

我使用这样的脚本来创建用户:

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 变量,为其中之一设置默认值实际上解决了这个问题。这真的很奇怪,但我希望有一天这能帮助一些可怜的灵魂:)

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

我在构建 sql 项目时遇到了同样的错误,但场景不同且棘手。

我在我的一个数据库 table 中引入了新列,我需要为该 table 中已有的行填充该列。所以基本上它应该是一次性过程,因此我决定创建 post 部署脚本来做到这一点。此 post 部署脚本

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

不用任何GO语句来处理这种情况

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