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

时间:2015-12-23 20:38:43

标签: sql-server ssms

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

  

SSTDB不存在。首先运行1MakeSSTDB.sql。退出脚本。

永远不会被执行。如果我注释掉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   数据库' SSTDB'不存在。确保正确输入名称。

2 个答案:

答案 0 :(得分:1)

是的SSMS总是验证对象的存在,即使您使用了这样的IF块。

执行所需操作的一种方法是使用动态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'

答案 1 :(得分:0)

通过执行SSDT可以做出相当可靠的版本:

  1. 使用SQLCMD模式
  2. 使用SET NOEXEC ON
  3. 测试SQLCMD模式以防用户忘记启用它
  4. 将整个脚本设置为在出错时退出而不是继续执行
  5. 这是根据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表不使用它们,并且在WHERE条件的右侧没有它们。