在SQL中使用记录作为表名

问题描述 投票:3回答:4

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

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 sql-server tsql
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];

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;
© www.soinside.com 2019 - 2024. All rights reserved.