【问题标题】:How to get a list of temporary tables created in a stored procedure?如何获取在存储过程中创建的临时表列表?
【发布时间】:2017-05-17 20:37:31
【问题描述】:

我有一个存储过程,我在其中创建了几个临时表。如何获取在该存储过程中创建的那些临时表的列表?

类似这样的:

SELECT [# temporary table name]
FROM sys.procedures
WHERE name = '<Stored Procedure Name>'

我想要这个结果

Temporary_Table_Name
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#TemporaryTable1
#TemporaryTable2
.
.
.
#TemporaryTableN

(N row(s) affected)

然后,使用该列表,我想动态构建 DROP TABLE 指令。

    Dinamic_DROP_Instruction
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IF OBJECT_ID('tempdb..#TemporaryTable1') IS NOT NULL DROP TABLE #TemporaryTable1
IF OBJECT_ID('tempdb..#TemporaryTable2') IS NOT NULL DROP TABLE #TemporaryTable1
.
.
.
IF OBJECT_ID('tempdb..#TemporaryTableN') IS NOT NULL DROP TABLE #TemporaryTableN

(N row(s) affected)

【问题讨论】:

  • 为什么需要动态执行此操作?对您的过程执行 control+F,找到所有临时表,然后在开头写入(或复制/粘贴)您的条件 drop 和/或 table drops 在末尾。
  • @dfundako 这是一个经常性且非常手动的过程,在大型程序中可能需要大量时间。否则找到“#”可能是在创建临时表时,就像在使用它们一样,这不是我需要的。
  • @marc_s 也许你知道我怎样才能得到这个脚本?
  • 给没有评论过这个话题的人添加句柄不会通知他们
  • @dfundako 我要解决我自己的问题,请检查一下!

标签: sql sql-server tsql stored-procedures temp-tables


【解决方案1】:

我能够构建一个代码来获取临时表列表,并设置动态指令以删除每个临时表(如果存在)。

我留下了我所基于的源代码和链接。

代码:

DECLARE @NameStoreProcedure AS VARCHAR(100) = 'Name_of_store_procedure' --Do not place the scheme

IF OBJECT_ID('tempdb..#Positions') IS NOT NULL
    DROP TABLE #Positions

IF OBJECT_ID('tempdb..#TemporalTableNames') IS NOT NULL
    DROP TABLE #TemporalTableNames

--Find all positions: http://dba.stackexchange.com/questions/41961/how-to-find-all-positions-of-a-string-within-another-string
DECLARE @term CHAR(20) = 'create'
DECLARE @string VARCHAR(MAX)

SELECT @string = OBJECT_DEFINITION(object_id)
FROM sys.procedures
WHERE NAME = @NameStoreProcedure

SET @string += '.' --Add any data here (different from the one searched) to get the position of the last character

------------------------------------------------------------------------------------------------------------------------
--Range of numbers: http://stackoverflow.com/questions/21425546/how-to-generate-a-range-of-numbers-between-two-numbers-in-sql-server
DECLARE @min BIGINT
    , @max BIGINT

SELECT @Min = 1
    , @Max = len(@string)
------------------------------------------------------------------------------------------------------------------------

--Get positions of 'CREATE'
SELECT pos = Number - LEN(@term)
INTO #Positions
FROM (
    SELECT Number
        , Item = LTRIM(RTRIM(SUBSTRING(@string, Number, CHARINDEX(@term, @string + @term, Number) - Number)))
    FROM (
        SELECT TOP (@Max - @Min + 1) @Min - 1 + row_number() OVER (
                ORDER BY t1.number
                ) AS N
        FROM master..spt_values t1
        CROSS JOIN master..spt_values t2
        ) AS n(Number)
    WHERE Number > 1
        AND Number <= CONVERT(INT, LEN(@string))
        AND SUBSTRING(@term + @string, Number, LEN(@term)) = @term
    ) AS y

SELECT RTRIM(LTRIM(REPLACE(REPLACE(REPLACE(substring(@string, pos - 1, CHARINDEX('(', @string, pos) - pos + 1), CHAR(9), ''), CHAR(13), ''), CHAR(10), ''))) AS NAME
INTO #TemporalTableNames
FROM #Positions
WHERE substring(@string, pos - 1, CHARINDEX('(', @string, pos) - pos + 1) LIKE '#%'

--List of temporary tables
SELECT NAME
FROM #TemporalTableNames

/*
--Dynamic Instruction for DROP instructios
    SELECT 'IF OBJECT_ID(''tempdb..' + NAME + ''') IS NOT NULL DROP TABLE ' + NAME
    FROM #TemporalTableNames
*/
【解决方案2】:

评论太长了......

这并不容易,可能需要一个解析函数。首先,使用OBJECT_DEFINITIONsp_helptext 或查看sys.sql_modules 或您想要获得定义的任何其他方法。然后,您必须根据 # 或您想要的任何其他方法搜索您的临时表,然后拆分它们。恕我直言,这将非常混乱且容易出错。这是一个开始。

 SELECT 
    SUBSTRING(
            OBJECT_DEFINITION(OBJECT_ID('yourProcedure')),
            CHARINDEX('#',OBJECT_DEFINITION(OBJECT_ID('yourProcedure'))),
            60)

60 在这里只是一个虚构的数字。您希望在 # 或类似内容之后找到第一个空格。同样,我认为除了在您的程序中使用 CONTROL+F 并手动添加 DROPstatements...

【讨论】:

  • 这是一个很好的方法。我只是在考虑使用 OBJECT_DEFINITION。但是,我正在使用您的代码并且得到 NULL。我尝试使用架构但不使用架构,但它不返回数据。
  • @JotaPardo 您是否传入了一个您确定其中有临时表的过程名称?请注意,您必须用上面的过程替换两个地方。
猜你喜欢
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
  • 2012-03-07
  • 1970-01-01
相关资源
最近更新 更多