循环遍历具有变量名称的不同表

时间:2017-03-02 15:25:39

标签: mysql sql

我知道你会说“这是一个可怕的设计”。我知道,过去几个月我一直在处理它(再次,这不是我的设计),但不是给我烫伤,请耐心帮我解答,是吗?谢谢!

我有一个表,其中包含一些其他表的名称列表:

Table_that_store_the_others_tables_names
------------------
| LIST_OF_TABLES |
------------------
| table_arw      |
------------------
| table_bhj      |
------------------
| table_cde      |
------------------

重要的是要知道这些表没有通用名称,但确实具有完全相同的结构:

each_one_of_those_dumb_tables, e.g. table_arw
--------------------------
| field1     | field2    |
--------------------------
| something  | something |
--------------------------
| something  | something |
--------------------------

所以,我需要做的是迭代这些表并获取他们拥有的数据(我很确定它是通过过程语言完成的,但我不太了解它)以某种方式:

loop through each value found in "Table_that_store_the_others_tables_names":
    select field1, field2 from "whatever_value_was_found"
    insert into "this_new_not_stupid_table_that_will_now_have_the_info"
end loop

所以,我认为就是这样。非常感谢你!

4 个答案:

答案 0 :(得分:2)

以下是如何使用动态sql执行此操作的方法。这里不需要游标或循环。这样的事情应该指出你在一个基于集合的方向。它比使用游标快得多,并且需要的代码也少得多。 :)

declare @SQL nvarchar(max) = N'insert into this_new_not_stupid_table_that_will_now_have_the_info(field1, field2) '

select @SQL = @SQL + N'select field1, field2 
from ' + quotename(t.LIST_OF_TABLES) + ' UNION ALL '
from Table_that_store_the_others_tables_names t

set @SQL = left(@SQL, len(@SQL) - 10)

exec sp_executesql @SQL

答案 1 :(得分:2)

Declare @SQL varchar(max)='Insert Into YourNewTable (Field1,Field2) >>>'
Select @SQL = Replace(@SQL+'Union All Select Field1,Field2 From '+QuoteName(YourFieldWithTableNames) +' where 1=1 ','>>>Union All ','')
 From  YourTable

Exec(@SQL)

生成的SQL看起来像这样

Insert Into YourNewTable (Field1,Field2) 
Select Field1,Field2 From [table_arw] where 1=1   << Notice I added a WHERE just in case
Union All 
Select Field1,Field2 From [table_bhj] where 1=1 
Union All 
Select Field1,Field2 From [table_cde] where 1=1 

答案 2 :(得分:1)

快速搜索this StackOverflow post。基本上,您需要将表名设置为变量,然后可以使用EXEC执行查询。

希望这有帮助!

答案 3 :(得分:1)

你的意思是这样吗?

DECLARE @dbID INT
DECLARE @dbName VARCHAR(50)
DECLARE @tblID INT
DECLARE @DynamicSQL VARCHAR(MAX)
DECLARE @tblName VARCHAR(100)

DECLARE @DB TABLE(DatabaseID INT,DatabaseName VARCHAR(50))
INSERT INTO @DB
SELECT DatabaseID
     , DatabaseName
FROM Archive..Databases
WHERE ArchiveYN = 1

DECLARE db_cursor CURSOR FOR 
SELECT DatabaseID     
FROM @DB

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @dbID 

WHILE @@FETCH_STATUS = 0   
BEGIN  
      DECLARE @DBTable TABLE(DBTableID INT,DBTableName VARCHAR(100),WeeksToKeep INT,DateColumnName VARCHAR(50))
      INSERT INTO @DBTable
      SELECT DBTableID
            ,DBTableName                
      FROM Archive..DBTables 
      WHERE DatabaseID = @dbID
        AND ArchiveYN = 1
        AND SchemaValidYN = 1

      SET @dbName = (SELECT DatabaseName FROM @DB WHERE DatabaseID = @dbID)

      DECLARE tbl_cursor CURSOR FOR  
      SELECT DBTableID
      FROM @DBTable

      OPEN tbl_cursor   
      FETCH NEXT FROM tbl_cursor INTO @tblID
      WHILE @@FETCH_STATUS = 0   
      BEGIN 

         SELECT @tblName = DBTableName                
         FROM @DBTable
         WHERE DBTableID = @tblID

         DECLARE @conDBName VARCHAR(100) =  @dbName + '_Archive.dbo'

         EXEC [dbo].[DropConstraints] @tblName ,@conDBName       

         IF EXISTS (SELECT * from syscolumns where id = Object_ID(@tblName) and colstat & 1 = 1)
         BEGIN
            SET @DynamicSQL =  'SET IDENTITY_INSERT ' + @dbName + '_Archive.dbo.' + @tblName + ' ON'
            EXEC (@DynamicSQL)
         END

         SET @DynamicSQL =  'INSERT INTO ' + @dbName + '_Archive.dbo.' + @tblName +  ' SELECT * FROM  ' + @dbName + '..' + @tblName
         EXEC (@DynamicSQL)

         SET @DynamicSQL = 'DELETE FROM ' + @dbName + '..' + @tblName
         EXEC (@DynamicSQL)

         IF EXISTS (SELECT * from syscolumns where id = Object_ID(@tblName) and colstat & 1 = 1)
         BEGIN
            SET @DynamicSQL =  'SET IDENTITY_INSERT ' + @dbName + '_Archive.dbo.' + @tblName + ' OFF'
            EXEC (@DynamicSQL)
         END                   

       FETCH NEXT FROM tbl_cursor INTO @tblID   
       END  

       CLOSE tbl_cursor   
       DEALLOCATE tbl_cursor
  FETCH NEXT FROM db_cursor INTO @dbID   
END   

CLOSE db_cursor   
DEALLOCATE db_cursor