在 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 2014 中继续发生。
我发现将分号放在 BEGIN 末尾会有所帮助。
这种方法有错误
IF 'A'='A'
BEGIN
THROW 51000, 'ERROR', 1;
END;
而且这种方法没有错误
IF 'A'='A'
BEGIN;
THROW 51000, 'ERROR', 1;
END;
为了解决您的问题,
“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的新特性。
对于 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
将
;
放在 THROW
关键字之前即可。
如果您错误地编码,也可能会发生此错误:
RAISEERROR('your message here',16,1)
我盯着它看了四个小时,在各处都加上了分号,然后才意识到我拼错了“RAISERROR”
正如很多答案所指出的,THROW语句是在SQL Server 2012中引入的。因此,如果您使用的是此版本的SQL Server或更高版本,建议使用THROW,否则使用RAISERROR。
此外,THROW 语句之前的语句后面必须跟分号(;)语句终止符。这就是为什么你必须在抛出之前包含一个分号。
查看这篇文章,了解Sql Server 中 RAISERROR 和 THROW 的区别
我还想鼓励您阅读 MSDN THROW (Transact-SQL) 中的文档,其中在备注部分解释了这些问题。
感谢您提出这个问题。虽然 IDE 给出语法错误,但我发现它编译并运行良好(注意,我使用的是 SQL Server 2016)。
我还发现,如果只需要一条语句,我可以直接使用
ELSE
THROW 99001, 'O associated with the given Q Id already exists', 1;
这不会显示语法错误消息。