我知道我要提出的这个问题很常见,但我无法使用其他例子。
我有一个使用表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
答案 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之外创建它。 (如果它是批处理的一部分,则在关闭连接时将删除临时表,或者您可以显式删除它。)