Sql server 为什么查询执行在返回后继续?

Sql server 为什么查询执行在返回后继续?,sql-server,tsql,Sql Server,Tsql,考虑以下脚本: IF OBJECT_ID('tempdb.dbo.#INTERMED', 'U') IS NOT NULL DROP TABLE #INTERMED; IF OBJECT_ID('tempdb.dbo.#INTERMED1', 'U') IS NOT NULL DROP TABLE #INTERMED1; PRINT 'Inserting INTO #INTERMED' GO SELECT 11 AS Col1 INTO #INTERMED RETUR

考虑以下脚本:

IF OBJECT_ID('tempdb.dbo.#INTERMED', 'U') IS NOT NULL
    DROP TABLE #INTERMED; 

IF OBJECT_ID('tempdb.dbo.#INTERMED1', 'U') IS NOT NULL
    DROP TABLE #INTERMED1; 

PRINT 'Inserting INTO #INTERMED'
GO

SELECT 11 AS Col1
INTO #INTERMED

RETURN -- Why does execution continue below this line?

PRINT 'Inserting INTO #INTERMED1' -- This doesn't print anything
GO
SELECT 'Testing testing 123' AS Col2 
INTO #INTERMED1

SELECT * FROM #INTERMED1 i
当您在SSMS中运行它时,您会注意到RETURN被忽略,RETURN后的PRINT语句不起任何作用,然后继续执行

有人能解释一下原因吗?我希望它在返回后立即退出

我确实发现它与GO语句有某种联系,因为如果我注释掉所有GO语句,它的行为与预期的一样(返回后退出),但我仍然没有解释。

GO
不是SQL语言的一部分。它是ManagementStudio使用的批处理分隔符,也被其他一些工具作为惯例采用,但在语言本身中没有特殊意义。尝试在存储过程中使用它,看看我的意思

因此,发生的情况是,您有一批如下所示:

IF OBJECT_ID('tempdb.dbo.#INTERMED', 'U') IS NOT NULL
    DROP TABLE #INTERMED; 

IF OBJECT_ID('tempdb.dbo.#INTERMED1', 'U') IS NOT NULL
    DROP TABLE #INTERMED1; 

PRINT 'Inserting INTO #INTERMED'
SELECT 11 AS Col1
INTO #INTERMED

RETURN -- Why does execution continue below this line?

PRINT 'Inserting INTO #INTERMED1' -- This doesn't print anything
它做的是它的东西,然后你有一个新的批次,看起来像这样:

IF OBJECT_ID('tempdb.dbo.#INTERMED', 'U') IS NOT NULL
    DROP TABLE #INTERMED; 

IF OBJECT_ID('tempdb.dbo.#INTERMED1', 'U') IS NOT NULL
    DROP TABLE #INTERMED1; 

PRINT 'Inserting INTO #INTERMED'
SELECT 11 AS Col1
INTO #INTERMED

RETURN -- Why does execution continue below this line?

PRINT 'Inserting INTO #INTERMED1' -- This doesn't print anything
它运行到
RETURN
语句,此时批处理返回/完成,只有该批处理返回/完成。但是,还有一个批处理要运行:

SELECT 'Testing testing 123' AS Col2 
INTO #INTERMED1

SELECT * FROM #INTERMED1 i
同样,这是一个全新的批次。前面的
RETURN
语句没有任何意义。就像你按顺序调用了三个方法


我在评论中也看到了这一点:

我之所以这样做,是为了让PRINT语句在脚本仍在执行时输出一些东西

有更好的办法。查看
RAISERROR
语句:

RAISERROR('My Progress Message',0,1) WITH NOWAIT

因为你有机会。MST-Sql中的GO作为一个全新的脚本批处理。你到底在用go做什么?go定义了batch语句——当你运行这个语句时,你运行的是3个独立的语句——return存在于当前语句中,并运行下一个语句。Charleh:这是原始脚本的简化版本。原始脚本有多个部分,需要一段时间才能执行。我之所以这么做,是为了在脚本仍在执行时让PRINT语句输出一些东西。请参阅下面的我的答案,以获得更好的方法。使用RAISERROR而不是PRINT的好技巧。我注释掉了GO,并用RAISERROR替换了PRINT。它可以工作,但如果我使用0表示严重性,是否保证它不会中断执行?我详细介绍了如何使用RAISERROR,您的示例需要在末尾添加NOWAIT,因为严重性是安全的,谢谢您提醒我NOWAIT。当我使用普通键盘而不是手机时,我将进行编辑。