【发布时间】:2017-02-06 20:10:52
【问题描述】:
当您收到错误消息并在 SSMS 中收到一条包含错误代码行的消息时,您会想要查找该行的内容。
但是我遇到了一个错误。 如果您在 SQL Server 上运行以下代码,您将获得递归函数调用。看起来 ALTER 接受 EXEC 作为存储过程的一部分,即使它位于 AS BEGIN...END 行之后。
ALTER PROCEDURE SP_GetErrorLine(
@lineNum INT,
@spName NVARCHAR(250)
) AS BEGIN
SET NOCOUNT ON
CREATE TABLE #spLine (
line INT NOT NULL IDENTITY(1,1),
Bob NVARCHAR(2048) NOT NULL
)
INSERT INTO #spLine (Bob)
EXEC sp_helptext @spName
DECLARE @line NVARCHAR(2048)
SELECT @line=Bob FROM #spLine
WHERE line=@lineNum
DROP TABLE #spLine;
SELECT @lineNum AS [Line No.], LTRIM(RTRIM(@line)) AS [SP Line]
END
EXEC SP_GetErrorLine 67, 'SP_AnotherProcedure'
(您需要将 SP_AnotherProcedure 替换为您在同一数据库中的任何其他存储过程来运行它。)
这是预期的行为,还是错误解析代码?
干杯
【问题讨论】:
-
BEGIN/END 不是批处理终止符。你所经历的正是它应该如何表现。如果您想拥有多个脚本,则需要在批次之间放置批次分隔符。默认的批处理分隔符是 GO。不是你的问题的答案,但你可以看看这篇文章。 sqlperformance.com/2012/10/t-sql-queries/sp_prefix
-
为了进一步说明肖恩的观点,请取出
BEGIN/END(它们不是必需的)。存储过程仍然被创建。 SQL Server 将END视为块的结束,而不是过程的结束,因此它之后的任何内容也将成为过程的一部分。 -
啊,谢谢@SeanLange,不知道性能花絮。是时候进行一些重命名了。
-
让我感到困惑的是它毫无怨言地接受了
AS BEGIN ... END,并且如果函数是多行的,则需要使用BEGIN...END,所以我认为这里就是这种情况.您可以在没有IF (X)或AS之前使用BEGIN/END,用于范围界定或其他什么? (我来自 C++,你可以这样使用{}s) -
是的,您也可以使用任意数量的它们。它只划分与批处理不同的代码块。
标签: sql-server stored-procedures sql-server-2016