使用变量名动态查询 table 会产生模糊的 "Incorrect syntax near 'Select'" 错误

Dynamically querying a table with a variable name yields a vague "Incorrect syntax near 'Select'" Error

我正在尝试使用动态生成的名称查询现有 table 中的前 5 行。我知道 SO 上的许多人 problems/questions 做过类似的事情,我已经阅读了一些解决方案,但都无济于事。

我可以很好地生成 table 名称;然后问题是采用 table 名称并在另一个脚本中使用它,即 SELECT TOP 5 * FROM (table name here).

这是我现在拥有的:

DECLARE @oldtablename VARCHAR(MAX)
DECLARE @oldtablequery VARCHAR(MAX)

SET @oldtablename = 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE ''%tablekeywords_test%'' 
AND CONVERT(varchar(8), RIGHT(TABLE_NAME, 8), 112) <= CONVERT(VARCHAR(8), GETDATE(), 112)'
exec(@oldtablename)

-- up until here, everything works fine. The following does not:
--EXEC('select top 5 * from databasename.dbo.'+@oldtablename+'')
SET @oldtablequery = 'SELECT TOP 5 * FROM databasename.dbo.'+@oldtablename+';'
exec(@oldtablequery)

我在 exec( ) 尝试(评论中的那个)和 Set...exec 尝试中遇到的错误是:

(1 row(s) affected)
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'SELECT'.

不幸的是,我不知道编译器指的是哪个 'SELECT' 错误。我猜这不是语法错误,但可能是逻辑错误(即,我正在做或没有做一些基本的事情,而不是省略逗号或其他东西),但我不完全确定,因为我我是动态 SQL 的新手。

提前谢谢你。

编辑澄清: 我并不费力地生成或打印所需的 table 名称。我正在尝试在新查询中使用 table 名称 select 该特定 table、@oldtablename.

的前 5 行

您的第一个查询正在返回一个查询,即 select 语句。
您的第二个查询试图 select 前 5 名...来自 select 语句...这没有意义。

请查看以下内容 - 这是您的查询,更改为打印出查询而不是执行查询。看看它打印出来的那个查询,这个问题应该是不言自明的。

DECLARE @oldtablename VARCHAR(MAX)
DECLARE @oldtablequery VARCHAR(MAX)

SET @oldtablename = 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE ''%tablekeywords_test%'' 
AND CONVERT(varchar(8), RIGHT(TABLE_NAME, 8), 112) <= CONVERT(VARCHAR(8), GETDATE(), 112)'
exec(@oldtablename)

-- up until here, everything works fine. The following does not:
--EXEC('select top 5 * from databasename.dbo.'+@oldtablename+'')
SET @oldtablequery = 'SELECT TOP 5 * FROM databasename.dbo.'+@oldtablename+';'
print @oldtablequery

如果您只想保留第一个查询中的 table 名称,则需要使用第二个变量来捕获它。

Eli的回答指出了问题所在。没有必要在第一个查询中使用动态 SQL。这将解决问题:

DECLARE @oldtablename VARCHAR(MAX)
DECLARE @oldtablequery VARCHAR(MAX)

SET @oldtablename = (
     SELECT 
         TOP 1 TABLE_NAME 
     FROM INFORMATION_SCHEMA.TABLES 
     WHERE TABLE_NAME LIKE '%tablekeywords_test%' 
     AND CONVERT(varchar(8), RIGHT(TABLE_NAME, 8), 112) <= CONVERT(VARCHAR(8), GETDATE(), 112));


-- up until here, everything works fine. The following does not:
--EXEC('select top 5 * from databasename.dbo.'+@oldtablename+'')
SET @oldtablequery = 'SELECT TOP 5 * FROM databasename.dbo.'+@oldtablename+';'
exec(@oldtablequery)