运行 脚本时,如何阻止 SSMS 检查数据库是否存在?

How can I stop SSMS from checking database existence when running a script?

我有一个脚本可以检查数据库是否存在,如果不存在则优雅地退出并为用户提供一些说明。但是,当数据库不存在时,SSMS 会将 USE 语句标记为错误并生成自己的错误,甚至没有 运行 我的脚本。所以在下面的代码中,行

SSTDB doesnot exist. Run 1MakeSSTDB.sql first. Exiting script.

永远不会被执行。如果我注释掉 USE SSTDB 行,那么脚本会按预期工作。任何想法如何让它工作? (使用 SQLServer 2014。)

USE master
GO
IF NOT EXISTS (SELECT name 
 FROM master.dbo.sysdatabases 
 WHERE ('[' + name + ']' = N'SSTDB' OR name = N'SSTDB'))
BEGIN
 Print 'SSTDB doesnot exist. Run 1MakeSSTDB.sql first. Exiting script.'
END
ELSE
BEGIN
 Print 'exists'
 USE SSTDB
END
Print 'done'
来自 SSMS 的错误消息:

Msg 911, Level 16, State 1, Line 14 Database 'SSTDB' does not exist. Make sure that the name is entered correctly.

是的,即使您使用这样的 IF 块,SSMS 也会始终验证对象的存在。

一种方法是使用动态 sql,像这样:

USE master
GO
IF NOT EXISTS (SELECT name 
    FROM master.dbo.sysdatabases 
    WHERE ('[' + name + ']' = N'SSTDB' OR name = N'SSTDB'))
BEGIN
    Print 'SSTDB doesnot exist. Run 1MakeSSTDB.sql first. Exiting script.'
END
ELSE
BEGIN
    Print 'exists'
    DECLARE @sql varchar(max) = 
    'USE SSTDB;
    --All code here uses SSTDB database
    '    
    EXECUTE (@sql);
END
--All code here still uses master database
Print 'done'

您可以按照 SSDT 的做法制作一个相当可靠的版本:

  1. 使用 SQLCMD 模式
  2. 测试 SQLCMD 模式以防用户忘记启用它,使用 SET NOEXEC ON
  3. 将整个脚本设置为出错时退出而不是继续执行

这是改编自 SSDT 模板代码:

:on error exit
:setvar dbname SSTDB 

/*
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported.
To re-enable the script after enabling SQLCMD mode, execute the following line:
SET NOEXEC OFF; 
*/
:setvar __IsSqlCmdEnabled "True"
GO
IF N'$(__IsSqlCmdEnabled)' NOT LIKE N'True'
    BEGIN
        PRINT N'SQLCMD mode must be enabled to successfully execute this script.';
        SET NOEXEC ON;
    END
GO

IF NOT EXISTS (SELECT name 
    FROM master.dbo.sysdatabases 
    WHERE ( name = N'SSTDB' OR name = N'SSTDB')
) RAISERROR( 'SSTDB doesnot exist. Run 1MakeSSTDB.sql first. Exiting script.', 11, 1 )
GO

PRINT 'Starting script.'

USE $(dbname)
-- Do work

PRINT 'End script'
GO

另外 - 附带问题 - 方括号 '[' + name + ']' 看起来损坏了。 sysdatabases table 不使用它们,并且您没有在 WHERE 条件的右侧。