如果USE语句失败,如何停止执行SQL脚本(使用GO)?

如果USE语句失败,如何停止执行SQL脚本(使用GO)?

问题描述:

这有been asked many times,但最高评分的答案不起作用。如果USE语句失败,如何停止执行SQL脚本(使用GO)?

BEGIN TRY 
    USE [**DATABASE**] 
END TRY 
BEGIN CATCH 
    set noexec on 
    raiserror('Oh no a fatal error', 20, -1) with log  
    return 
END CATCH 

GO 
IF EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[xxxxx]') AND parent_object_id = OBJECT_ID(N'[dbo].[xxxxxx]')) 
ALTER TABLE [dbo].[xxxxx] DROP CONSTRAINT [xxxxxx] 
GO 

似乎无论我做什么IF EXISTS仍然运行。我试过GOTO。我试过set noexec on。我试过RETURN

它在USE语句中肯定失败,它在第一个GO之后肯定会继续运行下一个块。

这里的要点是,我将这个脚本给其他人,他们必须之前运行它设置数据库名称。但他们会忘记所以我需要一个很好的描述性错误信息。

+0

所以你不知道你运行脚本的数据库是否真的存在? – 2014-10-09 22:24:54

+0

我想我在OP中解释过。 – jcollum 2014-10-09 22:25:32

+0

@MattH:'TRY''附近语法不正确。 – jcollum 2014-10-09 22:39:31

如何:

IF db_id('myDatabase') is null 
    RAISERROR('Oh no a fatal error', 20, -1) with log  

PRINT 'Do some stuff' 
GO 

您可以使用DB_ID函数调用的参数(@MyDB)。

我真正的问题是为什么:

  • “用一个不存在的数据库”命令提出了一个严重16错误
  • 在catch块尝试的代码,以提高严重性20错误
  • 但是,CATCH块只会提高严重性16错误

这是为什么?

- 编辑----------------

BOL为USE声明说(不是太清楚了,恕我直言):执行

USE在编译和执行时都会立即生效 。因此,在指定的数据库中执行在执行 USE语句后出现在批处理中的语句。

因此,假设这里,错误是在编译时生成的,所以第一个“batch”(在第一个去之前)没有运行,并且执行直接跳转到第二个批处理。

+0

L20错误的要点是立即停止执行。但它似乎并没有在失败的USE中发挥作用。这是奇特的。 – jcollum 2014-10-09 22:59:18

+0

我可以在USE语句中使用@参数吗?不看这种方式给我。 – jcollum 2014-10-09 23:00:59

+0

不,USE不带参数。如果将其作为动态SQL运行,则上下文将仅在后续的动态SQL执行期间发生更改。 – 2014-10-10 14:01:46