8

我有一个包含一些 sql 脚本(DDL 和 DML)的 sql 文件,我通过从 windows 命令行调用来执行这些脚本。问题是当发生错误时它会报告错误,但文件中的所有 sql 语句仍在执行,而我希望一旦在其中一个 sql 语句中遇到第一个错误,执行应该就停止在那里。

我使用 sql server 作为我的数据库

以下是我的脚本示例

    CREATE TABLE #tmpErrors (Error int)
GO
SET XACT_ABORT ON
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
BEGIN TRANSACTION
GO

/** Main Scripts **/
PRINT N'Creating [dbo].[Student]'
GO
CREATE TABLE [dbo].[Student](
    [Id] [bigint] NOT NULL,
    [Subject] [varchar](15) NOT NULL,
    CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    )
)
GO
IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION
GO
IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END
GO

PRINT N'Adding [StudentID] column to [dbo].[School]'
GO
ALTER TABLE [dbo].[School] ADD [StudentID] [bigint] NULL
GO
IF @@ERROR<>0 AND @@TRANCOUNT>0 ROLLBACK TRANSACTION
GO
IF @@TRANCOUNT=0 BEGIN INSERT INTO #tmpErrors (Error) SELECT 1 BEGIN TRANSACTION END
GO

/***And many other DDL and DML statements, each followed by an error check***/


/**
 * Main teardown 
 */
IF EXISTS (SELECT * FROM #tmpErrors) ROLLBACK TRANSACTION
GO

IF @@TRANCOUNT>0 BEGIN
PRINT 'The database update succeeded'
COMMIT TRANSACTION
END
ELSE PRINT 'The database update failed'
GO

IF EXISTS (SELECT * FROM #tmpErrors) OR (@@ERROR<>0)
BEGIN
RAISERROR (N'An error was encountered', 20, 1 ) WITH LOG, NOWAIT, SETERROR SELECT @@ERROR AS error_number
END
GO

/**
 * Final teardown
 */
DROP TABLE #tmpErrors
GO
4

1 回答 1

8

我很确定BEGIN TRY并且BEGIN CATCH会在遇到错误时停止执行并将执行直接带到错误处理程序:

BEGIN TRY

   ' do stuff

END TRY
BEGIN CATCH

   'handle

END CATCH

编辑:这是一个例子:

BEGIN TRY

    DECLARE @int int
    SET @int = 1

    SET @int = 1 / 0

    SET @int = 2

    SELECT 'Everything OK'

END TRY
BEGIN CATCH

    SELECT 'Oops'

END CATCH

注释掉上面除以零的行以查看“一切正常”,否则您将在结果集中看到“糟糕”

于 2012-12-04T16:48:02.257 回答