动态SQL和字段名称数组中的对象名称#temp无效

问题描述:

我在两个单独的存储过程中使用#temp表。在一种情况下,它工作正常,而在其他情况下,它会给出错误“无效的对象名称#temp”。动态SQL和字段名称数组中的对象名称#temp无效

第一种情况:

SELECT SubsID, 
       SubsName, 
       AbbrName 
INTO   #TEMP 
FROM   SubsList 
WHERE  CAST (SubsID AS VARCHAR(10)) LIKE '%' + @intRight + '%' 
        OR SubsName LIKE '%' + @intRight + '%' 

它好的工作。

为了使这个SQL更具动态性,我使用QUOTENAME并做了以下更改: 1.我将@ColName,@sourceName,@intField和@txtField的数据类型设为sysname。 2.事实上,我删除了param @tableName作为sysname(值:#temp被传递给它),因为它在Select和Drop SQL中给出了错误。 3.我在@ColName中传递一个字段名称。当我通过所有三个字段名称时,它给了错误。 4.我声明@cmd nvarchar(max)并为其分配SQL以供执行。

SET @cmd = N'Select ' + QUOTENAME(@ColName) + 
      N' INTO #temp from ' + QUOTENAME(@sourceName) + 
      N' where CAST(' + QUOTENAME(@intField) + N' AS VARCHAR(10)) like ''%' + @strVal + 
      N'%'' or ' + QUOTENAME(@txtField) + ' like ''%' + @strVal + N'%''' --working 
EXEC sp_executesql @cmd; 

SELECT * 
FROM #temp; 

DROP TABLE #temp; 

我将EXEC sp_executesql @cmd更改为EXEC(@cmd),但仍然存在错误。

我得到无效对象名称的错误,但是如果我将#temp更改为## temp,则此错误不存在。

我的第一个问题:在使用#temp的情况下,这个错误有什么原因? 第二个问题:我如何制作字段名称数组并将其传递给存储过程?

+0

您应该将'@ strVal'作为参数传递给'sp_executesql',而不是将其简单地连接到为避免SQL注入而执行的字符串中。 – 2012-07-16 14:29:19

exec完成后,temp表超出了范围。'exec'或'sp_executesql'在他们自己的范围内运行。因此,像临时表和变量一样创建的任何东西都会在执行结束后被销毁或超出范围。认为这些存储过程像存储过程一样。

修复此问题。在主代码中创建临时表..然后使用dynmic sql插入它,然后在主代码中读取它。

+0

请访问以下链接,其中EXEC和sp_executesql以非常好的方式进行了解释。即使例子也很好理解: http://www.sommarskog.se/dynamic_sql.html#sp_executesqlong – 2012-07-19 02:59:18