在SQL中使用记录作为表名

3

我有一个表格,其中包含表名。我想运行一个查询来返回这些表名,然后将它们用作另一个查询的表名。

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)

我收到了以下错误信息:

Msg 512,级别16,状态1,第2行
子查询返回的值多于1个。 当子查询跟随=,!=,<,<=,>,> =时,不允许这种情况,或者当子查询用作表达式时。

我希望它能实现类似的功能:
SELECT * FROM table1
SELECT * FROM table2
SELECT * FROM table3

动态 SQL 搜索 - paparazzo
4个回答

2

用一点动态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];

我能够使用它得到我需要的东西。谢谢! - Lynx
@Lynx 很高兴能够帮助。 - John Cappelletti

0
每个使用 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

0
使用游标,您可以通过以下 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;

-1
你需要使用游标或循环。类似这样的代码可能适合你。
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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接