【问题标题】:How can I stop SSMS from checking database existence when running a script?运行脚本时如何阻止 SSMS 检查数据库是否存在?
【发布时间】:2015-12-25 00:14:22
【问题描述】:

我有一个脚本来检查数据库是否存在,如果它不存在,则会优雅地退出,并为用户提供一些说明。但是,当数据库不存在时,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 的错误消息:

消息 911,第 16 级,状态 1,第 14 行 数据库“SSTDB”不存在。确保名称输入正确。

【问题讨论】:

标签: sql-server ssms


【解决方案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'

【讨论】:

  • 嗯,是的,我并不是要暗示它不会。依赖于USE database 的所有内容都必须位于相同的动态上下文中。
  • 在所有 SQL 代码中转义引号可能会很痛苦。我更喜欢使用 SQLCMD 和纯 T-SQL。
【解决方案2】:

您可以通过 SSDT 所做的事情来制作一个相当可靠的版本:

  1. 使用 SQLCMD 模式
  2. 使用 SET NOEXEC ON 测试 SQLCMD 模式以防用户忘记启用它
  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 表不使用它们,并且在 WHERE 条件的右侧没有它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 2021-12-28
    相关资源
    最近更新 更多