T-SQL 抛出异常

问题描述 投票:0回答:7

在 T-SQL 存储过程中使用

THROW
语句时,我遇到了著名的“语法错误”。我已经用 Google 搜索并检查了 StackOverflow 上的问题,但提出的解决方案(奇怪的是,被接受)对我不起作用。

我正在修改存储过程如下:

ALTER PROCEDURE [dbo].[CONVERT_Q_TO_O]
    @Q_ID int = NULL,
    @IDENTITY INT = NULL OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @EXISTING_RECORD_COUNT [int];

    SELECT
        @EXISTING_RECORD_COUNT = COUNT (*)
    FROM
        [dbo].[O]
    WHERE
        [Q_ID] = @Q_ID

    IF @EXISTING_RECORD_COUNT = 0
    BEGIN
        -- DO SOME STUFF HERE

        -- RETURN NEW ID
        SELECT @IDENTITY = SCOPE_IDENTITY()
    END
    ELSE
    BEGIN
         THROW 99001, 'O associated with the given Q Id already exists', 1;
    END
END
GO

当我编写此 T-SQL 代码时,我收到一条错误消息

“THROW”附近的表述不正确。期待对话、对话、分布式或交易

所有解决方案都建议在“THROW”之前或“ELSE BEGIN”语句之后放置分号。当我修改 T-SQL 时,我只是收到“‘THROW’附近的错误语句”错误,并且似乎找不到解决方案。

有什么建议吗?

sql-server t-sql throw
7个回答
98
投票

这种情况在 SQL Server 2014 中继续发生。

我发现将分号放在 BEGIN 末尾会有所帮助。

这种方法有错误

IF 'A'='A'
BEGIN
   THROW 51000, 'ERROR', 1;
END;

而且这种方法没有错误

IF 'A'='A'
BEGIN;
  THROW 51000, 'ERROR', 1;
END;

47
投票

为了解决您的问题,

“THROW”附近的表述不正确。期待对话、对话、 分布式或交易

在 throw 语句前添加分号:

BEGIN
    ;THROW 99001, 'O associated with the given Q Id already exists', 1;
END

关于

“‘THROW’附近的陈述不正确”。

如果您使用的版本低于 SQL 2012,请尝试使用此功能:

RAISERROR('O associated with the given Q Id already exists',16,1);

因为THROW是SQL 2012的新特性。


43
投票

对于 SQL Server 2012 或更高版本:

;THROW 60000, 'your message here', 1

如果您想将变量传递给消息,请使用以下命令:

DECLARE
    @Errors INT = 2,
    @ErrMsg NVARCHAR(500)

SET @ErrMsg = 'You have '+CAST(@Errors AS NVARCHAR) + ' errors!'
;THROW 60000, @ErrMsg, 1

请注意,与 RAISERROR 不同,THROW 会阻止进一步的代码执行。

抛出文档

旧选项:

RAISERROR('your message here', 16, 1)

如果您想将变量传递给消息,请使用以下命令:

DECLARE
    @Errors INT = 2,
    @ErrMsg NVARCHAR(500)

SET @ErrMsg = 'You have '+CAST(@Errors AS NVARCHAR) + ' errors!'
RAISERROR(@ErrMsg, 16, 1)

查看sql server版本:

SELECT @@VERSION


12
投票

;
放在
THROW
关键字之前即可。


10
投票

如果您错误地编码,也可能会发生此错误:

RAISEERROR('your message here',16,1)

我盯着它看了四个小时,在各处都加上了分号,然后才意识到我拼错了“RAISERROR”


7
投票

正如很多答案所指出的,THROW语句是在SQL Server 2012中引入的。因此,如果您使用的是此版本的SQL Server或更高版本,建议使用THROW,否则使用RAISERROR。

此外,THROW 语句之前的语句后面必须跟分号(;)语句终止符。这就是为什么你必须在抛出之前包含一个分号。

查看这篇文章,了解Sql Server 中 RAISERROR 和 THROW 的区别

我还想鼓励您阅读 MSDN THROW (Transact-SQL) 中的文档,其中在备注部分解释了这些问题。


0
投票

感谢您提出这个问题。虽然 IDE 给出语法错误,但我发现它编译并运行良好(注意,我使用的是 SQL Server 2016)。

我还发现,如果只需要一条语句,我可以直接使用

ELSE 
    THROW 99001, 'O associated with the given Q Id already exists', 1;

这不会显示语法错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.