【问题标题】:Invalid object name #temp in Dynamic SQL and Array of field names动态 SQL 和字段名称数组中的对象名称 #temp 无效
【发布时间】:2012-07-16 14:20:12
【问题描述】:

我在两个单独的存储过程中使用#temp 表。在一种情况下,它可以正常工作,而在另一种情况下,它会给出错误“无效的对象名称#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.事实上,我删除了参数@tableName as sysname(值:#temp 已传递给它),因为它在Select and 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 时出现此错误的原因是什么? 第二个问题:如何制作字段名称数组并将其传递给存储过程?

【问题讨论】:

  • 您应该将@strVal 作为参数传递给sp_executesql,而不是简单地将其连接到执行的字符串中以避免SQL 注入。

标签: sql-server arrays temp


【解决方案1】:

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

要解决这个问题。在主代码中创建临时表。然后使用动态 sql 插入其中,然后在主代码中读取它。

【讨论】:

猜你喜欢
  • 2018-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多