【问题标题】:SQL Server combines CREATE/ALTER and EXECSQL Server 结合了 CREATE/ALTER 和 EXEC
【发布时间】: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


【解决方案1】:

BEGIN/END 不是批处理终止符。你所经历的正是它应该如何表现。如果您想拥有多个脚本,则需要在批次之间放置批次分隔符。默认的批处理分隔符是 GO。

话虽如此,您可以在一个批次中拥有任意数量的 BEGIN/END 块。真正的诀窍不是将批次与块混淆。

【讨论】:

  • 还值得注意的是,您不能在没有语句的情况下执行 BEGIN END —— 这被视为 END 附近的语法错误,这可能解释了为什么我没有意识到可以使用 BEGIN/END没有附加条件。
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多