循环遍历SQL表中包含其他表名称的列

时间:2014-06-25 13:05:40

标签: sql sql-server database sql-server-2008 sql-server-2008-r2

我对使用SQL相当新,目前我的表有一个列,其中包含我想要用于一个查询的所有表的名称,所以我想要做的是循环遍历该列并继续对于这些表中的每一个表,然后在其中一个列中搜索一个值(可能有多个值),因此每当表包含该值时,我将列出该表的名称。有人能给我一个如何做到这一点的暗示吗?是否需要游标?

2 个答案:

答案 0 :(得分:1)

我没有足够的声誉来评论,但是包含表名的列的表都在一列中,这意味着所有表名都以逗号分隔或用某种分隔符标记?这会导致查询稍微复杂一些,因为在开始遍历表之前必须先处理它。 但是,这需要一个游标,以及一些动态的sql。 我将举例说明如何解决这个问题。

declare @value varchar(50)
declare @tableName varchar(50)
declare @sqlstring nvarchar(100)
set @value = 'whateveryouwant'
declare @getTableName = cursor for
select tableName from TablewithTableNames
OPEN @getTableName
  fetch NEXT
  from @getTableName into @tableName
  while @@FETCH_STATUS = 0
  BEGIN
      set @sqlstring = 'Select Count(*) from ' + @tableName + 'where ColumnNameYouwant = ' + @value
      exec @sqlstring
      If @@ROWcount > 0
         insert into #temptable values (@tableName)
     fetch next
     from @getTableName into @tableName
  END
  select * from #temptable
  drop table #temptable
  close @getTableName
  deallocate @getTableName

由于时间限制原因,我目前无法对此进行测试,但这就是我要这样做的方法。

答案 1 :(得分:0)

您可以尝试这样的事情:

--Generate dynamic SQL
DECLARE @TablesToSearch TABLE (
    TableName VARCHAR(50));
INSERT INTO @TablesToSearch VALUES ('invoiceTbl');
DECLARE @SQL TABLE (
    RowNum INT,
    SQLText VARCHAR(500));
INSERT INTO
    @SQL
SELECT
    ROW_NUMBER() OVER (ORDER BY ts.TableName) AS RowNum,
    'SELECT * FROM ' + ts.TableName + ' WHERE ' + c.name + ' = 1;'
FROM
    @TablesToSearch ts
    INNER JOIN sys.tables t ON t.name = ts.TableName
    INNER JOIN sys.columns c ON c.object_id = t.object_id;

--Now run the queries
DECLARE @Count INT;
SELECT @Count = COUNT(*) FROM @SQL;
WHILE @Count > 0
BEGIN
    DECLARE @RowNum INT;
    DECLARE @SQLText VARCHAR(500);
    SELECT TOP 1 @RowNum = RowNum, @SQLText = SQLText FROM @SQL;
    EXEC (@SQLText);
    DELETE FROM @SQL WHERE RowNum = @RowNum;
    SELECT @Count = COUNT(*) FROM @SQL;
END;

您需要将我正在使用的“1”更改为您要查找的值,并可能添加CONVERT / CAST以确保该列是正确的数据类型?

您实际上说您想要表的名称,因此您需要将SQL更改为:

'SELECT ''' + ts.TableName + ''' FROM ' + ts.TableName + ' WHERE ' + c.name + ' = 1;'

另一个想法是,最好将结果插入临时表中,这样你可以在最后一次转出结果?