具有多个批次的SQL Server存储过程 - 重用临时表

时间:2017-09-27 17:40:01

标签: sql-server stored-procedures sql-server-2016

我有一个简短的SQL脚本,它已被使用了一段时间。它在脚本中重用了临时表,并且运行良好。

最近,我决定将整个过程放到一个程序中,虽然我有一个惊喜等着我 - 使用关键字GO来划分将脚本分成两批(这就是我能够重用临时表的方式) - 这就是SQL Server对我咆哮的原因。

这是一个显示脚本功能的简化脚本:

DROP TABLE IF EXISTS #temp;
SELECT
    'john' AS first_name
    ,'doe' AS last_name
INTO #temp;

SELECT * FROM #temp
GO 
TRUNCATE TABLE #temp;

DROP TABLE #temp;

SELECT
    'jane' AS first_name
    ,'doe' AS last_name
INTO #temp;

这是我在程序中尝试做的事情,虽然没有成功:

CREATE PROCEDURE #temp_proc 
AS
BEGIN
    DROP TABLE IF EXISTS #temp;
    SELECT
        'john' AS first_name
        ,'doe' AS last_name
    INTO #temp;

    SELECT * FROM #temp
    GO 
    TRUNCATE TABLE #temp;

    DROP TABLE #temp;   

    SELECT
        'jane' AS first_name
        ,'doe' AS last_name
    INTO #temp;
END

这是我尝试创建过程时收到的错误消息:

  

Msg 102,Level 15,State 1,Procedure #temp_proc,Line 10 [Batch Start Line 0]
  ' #temp'附近的语法不正确。

     

Msg 102,Level 15,State 1,Line 20
  ' END'附近的语法不正确。

目标:我想继续重复使用相同的临时表名称,但我想在程序中坚持所有这些。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

您不能在存储过程中使用GO。如果删除它,您的代码应按预期运行。如果稍后放弃,则无需截断表格。

答案 1 :(得分:1)

除了删除代码中的GO之外,您不能在存储过程中删除并重新创建相同的临时表; SQL Server忽略drop并尝试在两个SELECT INTO语句中创建相同的#表。

答案 2 :(得分:1)

抱歉,但没有 - 你不明白GO。它是应用程序理解和实现的关键字。它指示应用程序获取所有前面的脚本文本(直到脚本开头或上一个GO)并将其发送到db引擎以供执行。您的过程创建脚本将被解释并作为2个单独的批次执行(这就是GO被称为批处理分隔符的原因)。第一个是:

CREATE PROCEDURE #temp_proc 
AS
BEGIN
DROP TABLE IF EXISTS #temp;
SELECT
    'john' AS first_name
    ,'doe' AS last_name
INTO #temp;
SELECT * FROM #temp
GO 

其次是:

TRUNCATE TABLE #temp;
DROP TABLE #temp;   
SELECT
    'jane' AS first_name
    ,'doe' AS last_name
INTO #temp;
END

请注意,这只是创建您的程序。它与程序的执行方式无关。这里没有什么可以利用的 - 您不能使用" go"将您的过程定义或执行分成批次。所以,如果没有改变,你的想法和方向很简单。动态sql是一种可能性 - 但这是一个复杂程度,将挑战和征税。