临时表 - 临时表为空 - SQL Server

时间:2017-12-20 14:34:34

标签: sql-server stored-procedures

我知道我要提出的这个问题很常见,但我无法使用其他例子。

我有一个使用表Enum_Tables的存储过程(此表有其他表名)来搜索整个数据库中的特定字符串。结果存储在一个表格中,该表格为我提供了我想要的Enum_Tables特定行。

目前存储工作正常,但现在它正在数据库中创建SearchTMP。我不希望这样,我想要的是创建像#SearchTMP这样的临时表。我创建了临时表,我试图填充它,但它是空的。

我正在谈论的部分是在while逻辑中(WHILE EXISTS(SELECT 1 FROM @SQLTbl WHERE ISNULL(Execstatus,0)= 0))。

它正在检查SearchTMP中是否有值,并且因为它不是临时表,所以它在数据库中创建一个。我想将其更改为#SearchTMP。我创建了表,但是我无法填充它,因为我无法做到,我删除了该代码。我知道我需要进行插入,但是如何在不改变代码的情况下进行插入,并保持相同的逻辑。

这是我的存储过程代码:

ALTER PROCEDURE [dbo].[SearchTables_TEST] 
    --@Tablenames VARCHAR(500)
    @SearchStr NVARCHAR(60),
    @GenerateSQLOnly Bit = 0,
    @SchemaNames VARCHAR(500) ='%' 
AS
    SET NOCOUNT ON 

    DECLARE @MatchFound BIT 
    SELECT @MatchFound = 0 

    DECLARE @CheckTableNames Table (Schemaname sysname, Tablename sysname) 
    DECLARE @SearchStringTbl TABLE (SearchString VARCHAR(500)) 

    DECLARE @SQLTbl TABLE (Tablename SYSNAME, 
                           WHEREClause VARCHAR(MAX),
                           SQLStatement VARCHAR(MAX),
                           Execstatus BIT  
                          )

    DECLARE @SQL VARCHAR(MAX) 
    DECLARE @TableParamSQL VARCHAR(MAX) 
    DECLARE @SchemaParamSQL VARCHAR(MAX) 
    DECLARE @TblSQL VARCHAR(MAX) 
    DECLARE @tmpTblname sysname 
    DECLARE @ErrMsg VARCHAR(100)    

    IF LTRIM(RTRIM(@SchemaNames)) ='' 
    BEGIN 
        SELECT @SchemaNames = '%' 
    END 

    --IF CHARINDEX(',',@Tablenames) > 0  
    --    SELECT @TableParamSQL = 'SELECT ''' + REPLACE(@Tablenames,',','''as TblName UNION SELECT ''') + '''' 
    --ELSE 
    --    SELECT @TableParamSQL = 'SELECT ''' + @Tablenames + ''' as TblName ' 

    IF CHARINDEX(',',@SchemaNames) > 0  
        SELECT @SchemaParamSQL = 'SELECT ''' + REPLACE(@SchemaNames,',','''as SchemaName UNION SELECT ''') + '''' 
    ELSE 
        SELECT @SchemaParamSQL = 'SELECT ''' + @SchemaNames + ''' as SchemaName '  

    SELECT @TblSQL = 'SELECT SCh.NAME,T.NAME 
              FROM SYS.TABLES T 
              JOIN SYS.SCHEMAS SCh 
              ON SCh.SCHEMA_ID = T.SCHEMA_ID 
              INNER JOIN [DynaForms].[dbo].[Enums_Tables] et on 
                 (et.Id = T.NAME COLLATE Latin1_General_CI_AS)  '


    INSERT INTO @CheckTableNames 
    (Schemaname,Tablename) 
    EXEC(@TblSQL) 


IF NOT EXISTS(SELECT 1 FROM @CheckTableNames) 
BEGIN 

    SELECT @ErrMsg = 'No tables are found in this database ' + DB_NAME() + ' for the specified filter' 
    PRINT @ErrMsg 
    RETURN 

END 


IF LTRIM(RTRIM(@SearchStr)) ='' 
BEGIN 

    SELECT @ErrMsg = 'Please specify the search string in @SearchStr Parameter' 
    PRINT @ErrMsg 
    RETURN 
END 
ELSE 
BEGIN  
    SELECT @SearchStr = REPLACE(@SearchStr,',,,',',#DOUBLECOMMA#') 
    SELECT @SearchStr = REPLACE(@SearchStr,',,','#DOUBLECOMMA#') 

    SELECT @SearchStr = REPLACE(@SearchStr,'''','''''') 

    SELECT @SQL = 'SELECT ''' + REPLACE(@SearchStr,',','''as SearchString UNION SELECT ''') + '''' 



    INSERT INTO @SearchStringTbl 
    (SearchString) 
    EXEC(@SQL) 

    UPDATE @SearchStringTbl 
       SET SearchString = REPLACE(SearchString ,'#DOUBLECOMMA#',',') 
END 



INSERT INTO @SQLTbl 
( Tablename,WHEREClause) 
SELECT QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME), 
        ( 
            SELECT '[' + SC.Name + ']' + ' LIKE ''' + REPLACE(SearchSTR.SearchString,'''','''''') + ''' OR ' + CHAR(10) 
              FROM SYS.columns SC 
              JOIN SYS.types STy 
                ON STy.system_type_id = SC.system_type_id 
               AND STy.user_type_id =SC.user_type_id 
              CROSS JOIN @SearchStringTbl SearchSTR 
             WHERE STY.name in ('varchar','char','nvarchar','nchar','text') 
               AND SC.object_id = ST.object_id 
             ORDER BY SC.name 
            FOR XML PATH('') 
        ) 
  FROM  SYS.tables ST 
  JOIN @CheckTableNames chktbls 
    ON chktbls.Tablename = ST.name  
  JOIN SYS.schemas SCh 
    ON ST.schema_id = SCh.schema_id 
   AND Sch.name        = chktbls.Schemaname 
 WHERE ST.name <> 'SearchTMP'
  GROUP BY ST.object_id, QUOTENAME(SCh.name) + '.' +  QUOTENAME(ST.NAME) ; 




  UPDATE @SQLTbl SET SQLStatement = 'SELECT * INTO SearchTMP FROM ' + Tablename + ' WHERE ' + substring(WHEREClause,1,len(WHEREClause)-5) -- this line was uncomment


  DELETE FROM @SQLTbl 
   WHERE WHEREClause IS NULL 

 DECLARE @output TABLE (Id VARCHAR(50), Name VARCHAR(100)) 
 Create Table #SearchTMP (searchparameter varchar(200))


WHILE EXISTS (SELECT 1 FROM @SQLTbl WHERE ISNULL(Execstatus ,0) = 0) 
BEGIN 


    SELECT TOP 1 @tmpTblname = Tablename , @SQL = SQLStatement 
      FROM @SQLTbl  
     WHERE ISNULL(Execstatus ,0) = 0 

     IF @GenerateSQLOnly = 0 
     BEGIN 

        IF OBJECT_ID('SearchTMP','U') IS NOT NULL -- this line was uncomment
        DROP TABLE SearchTMP   -- this line was uncomment


        EXEC (@SQL) 


        IF EXISTS(SELECT 1 FROM SearchTMP)
        BEGIN 
            --SELECT parsename(@tmpTblname,1) FROM SearchTMP 
            SELECT @MatchFound = 1 

            INSERT INTO @output (Id, Name)
            Select * from [DynaForms].[dbo].[Enums_Tables] where id in (SELECT parsename(@tmpTblname,1) FROM SearchTMP) 
        END 

     END 
     ELSE 
     BEGIN 
         PRINT REPLICATE('-',100) 
         PRINT @tmpTblname 
         PRINT REPLICATE('-',100) 
         PRINT replace(@SQL,'INTO SearchTMP','') 
     END 

     UPDATE @SQLTbl 
        SET Execstatus = 1 
      WHERE Tablename = @tmpTblname 

END 

SELECT * FROM @output

IF @MatchFound = 0  
BEGIN 
    SELECT @ErrMsg = 'No Matches are found in this database ' + DB_NAME() + ' for the specified filter' 
    PRINT @ErrMsg 
    RETURN 
END 

SET NOCOUNT OFF 

1 个答案:

答案 0 :(得分:0)

如果要在动态查询中使用临时表,则必须先创建所述临时表,然后在动态查询中填充它。

CREATE TABLE #MyTempTable (ID INT NOT NULL);
DECLARE @STMT NVARCHAR(MAX) = N'INSERT INTO #MyTempTable (ID) SELECT ID FROM MyTable;';

EXEC sp_executesql
  @stmt = @STMT
;

SELECT ID FROM #MyTempTable;

由于临时表是在存储过程中创建的,因此它的范围限定为该存储过程,并在SP完成时自动删除。

如果要在SP之外使用所述临时表,则必须在SP之外创建它。 (如果它是批处理的一部分,则在关闭连接时将删除临时表,或者您可以显式删除它。)