我有一个表中包含表名。我想运行一个查询来返回它们,然后将它们用作另一个查询的表名。
select tablenames
from tablelist
结果:
tablenames
----------
table1
table2
table3
然后我想在查询中一起使用这些表名:
DECLARE @table_name varchar(max)
SET @table_name = (SELECT tablenames from tablelist)
EXEC('SELECT * FROM ' + @table_name)
我收到以下错误:
消息512,级别16,状态1,行2 子查询返回的值超过1。当子查询跟随=,!=,<,<=,>,> =或子查询用作表达式时,不允许这样做。
我希望它做的是类似的事情:
SELECT * FROM table1
SELECT * FROM table2
SELECT * FROM table3
用一点动态SQL
例
Declare @SQL varchar(max) = ''
Select @SQL = @SQL+'Select * From '+quotename(tablenames)+';'+char(13)
From tablelist
--Print @SQL
Exec(@SQL)
生成的SQL看起来像这样
Select * From [table1];
Select * From [table2];
Select * From [table3];
每个使用SQL Server的人都有一个包含表名的表 - sys.tables:
SELECT
t.name
FROM
sys.tables t
JOIN
sys.schemas s
ON
s.schema_id = t.schema_id
WHERE
t.name NOT IN ('sysdiagrams')
下面的SQL将创建一个输出,其中包含您找到上述查询的每个表以及表计数。如果您只想使用特定的表,请编辑更新@Columns的查询以获取所需的表名:
DECLARE
@Columns NVARCHAR(MAX),
@SQL_Statement NVARCHAR(MAX)
SELECT
@Columns = ISNULL( @Columns + ', ', '') + 'SELECT TblName = ''' +t.name+''', NbrOfRows = COUNT(*) FROM ' + t.name
FROM
sys.tables t
JOIN
sys.schemas s
ON
s.schema_id = t.schema_id
WHERE
t.name NOT IN ('sysdiagrams')
SELECT
@Columns = REPLACE(@Columns, ', SELECT', ' UNION SELECT')
SELECT @SQL_Statement = '' + @Columns + ''
EXEC SP_EXECUTESQL @SQL_Statement = @SQL_Statement
您可以更改此选项以使用表名表:
DECLARE
@Columns NVARCHAR(MAX),
@SQL_Statement NVARCHAR(MAX)
SELECT
@Columns = ISNULL( @Columns + ', ', '') + 'SELECT TblName = ''' +t.tablesname+''', NbrOfRows = COUNT(*) FROM ' + t.tablenames
FROM
tablelist
SELECT
@Columns = REPLACE(@Columns, ', SELECT', ' UNION SELECT')
SELECT @SQL_Statement = '' + @Columns + ''
EXEC SP_EXECUTESQL @SQL_Statement = @SQL_Statement
使用游标,您可以使用以下SQL实现您要执行的操作。
DECLARE @tableList CURSOR;
DECLARE @tableName VARCHAR(50);
DECLARE @cmd NVARCHAR(500);
BEGIN
SET @tableList = CURSOR FOR
SELECT tableName
FROM dbo.tableList
OPEN @tableList
FETCH NEXT
FROM @tableList
INTO @tableName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = N'SELECT * FROM ' + @tableName
PRINT @cmd
EXEC sp_executeSQL @cmd
FETCH NEXT
FROM @tableList
INTO @tableName
END;
CLOSE @tableList ;
DEALLOCATE @tableList;
END;
您需要使用游标或循环。这样的事可能适合你。
DECLARE @table_name varchar(max)
SELECT @table_name = MIN(tablenames) FROM tablelist;
WHILE @table_name IS NOT NULL
BEGIN
EXEC('SELECT * FROM ' + @table_name)
SELECT @table_name = MIN(tablenames) FROM tablelist WHERE tablenames > @table_name;
END;