SQL Server: Search all tables for a particular GUID

前端 未结 5 2145
说谎
说谎 2021-02-03 23:10

i came across the need to cleanse some data, and i need to find some particular guids (i.e. uniqueidentifiers) in SQL Server°.

i\'ve come up with a stor

5条回答
  •  半阙折子戏
    2021-02-03 23:56

    Here's a solution for SQL 2000, with gratuitous use of cursors:

    declare @searchvalue uniqueidentifier
    set @searchValue = '{2A6814B9-8261-452D-A144-13264433864E}'
    
    if object_id('tempdb..#results') is not null drop table #results
    create table #results (TableSchema sysname, TableName sysname)
    
    declare @sql nvarchar(4000)
    
    declare @cursor1 cursor
    declare @tablename sysname
    declare @tableschema sysname
    
    declare @cursor2 cursor
    declare @columnname sysname
    declare @searchFields nvarchar(4000)
    
    set @cursor1 = cursor for
      select t.TABLE_SCHEMA, t.TABLE_NAME
      from INFORMATION_SCHEMA.Tables t
      where t.TABLE_TYPE = 'BASE TABLE'
        and exists (
          select * from INFORMATION_SCHEMA.Columns c
          where c.TABLE_NAME = t.TABLE_NAME
            and c.TABLE_SCHEMA = t.TABLE_SCHEMA
            and c.DATA_TYPE = 'uniqueidentifier'
          )
    
    open @cursor1
    while 1=1 begin
      fetch next from @cursor1 into @tableschema, @tablename
      if @@fetch_status <> 0 break
    
      set @searchFields = ''
      set @cursor2 = cursor for 
        select c.COLUMN_NAME
        from INFORMATION_SCHEMA.Columns c
        where c.TABLE_NAME = @tablename
          and c.TABLE_SCHEMA = @tableschema
          and c.DATA_TYPE = 'uniqueidentifier'
    
      open @cursor2
      while 1=1 begin
        fetch next from @cursor2 into @columnname
        if @@fetch_status <> 0 break
        set @searchFields = @searchFields + ', ' + quotename(@columnname)
      end      
    
      set @searchFields = substring(@searchFields,3,len(@searchFields))
      set @sql = ' insert #results'
               + ' select '''+@tableschema+''','''+@tablename+''''
               + ' from '+quotename(@tableschema)+'.'+quotename(@tablename)
               + ' where @searchValue in ('+@searchFields+')'
    
      print @sql
      exec sp_executesql @sql, N'@searchValue uniqueidentifier', @searchValue
    end
    
    select * from #results
    

    Here's a solution for SQL 2005, based on Remus's solution, with temp tables for better scaling:

    DECLARE @searchValue uniqueidentifier
    SET @searchValue = '{2A6814B9-8261-452D-A144-13264433864E}'
    
    IF OBJECT_ID('tempdb..#results') IS NOT NULL DROP TABLE #results
    CREATE TABLE #results (TableSchema SYSNAME, TableName SYSNAME);
    DECLARE @sql NVARCHAR(MAX);
    WITH cte_all_tables(SQL) AS (
        SELECT
              N' INSERT #results (TableSchema, TableName)'
            + N' SELECT ''' + t.TABLE_SCHEMA + ''', ''' + t.TABLE_NAME + N'''' 
            + N' FROM ' + QUOTENAME(t.TABLE_SCHEMA) + '.' +QUOTENAME(t.TABLE_NAME)
            + N' WHERE ' +
            (
                    SELECT QUOTENAME(c.COLUMN_NAME) + N' = @searchValue OR '
                    FROM INFORMATION_SCHEMA.Columns c
                    WHERE c.TABLE_NAME = t.TABLE_NAME
                            AND c.TABLE_SCHEMA = t.TABLE_SCHEMA
                            AND c.DATA_TYPE = 'uniqueidentifier'
                    FOR XML PATH('')
            ) + N'0=1'
       FROM INFORMATION_SCHEMA.Columns c
            INNER JOIN INFORMATION_SCHEMA.Tables t
            ON c.TABLE_NAME = t.TABLE_NAME
            AND t.TABLE_SCHEMA = c.TABLE_SCHEMA
            AND t.TABLE_TYPE = 'BASE TABLE'
        WHERE DATA_TYPE = 'uniqueidentifier')
    SELECT @sql = (SELECT [SQL]+nchar(10) FROM cte_all_tables FOR XML PATH(''));
    
    PRINT @SQL;
    exec sp_executesql @sql, N'@searchValue uniqueidentifier', @searchValue;
    SELECT * FROM #results
    

提交回复
热议问题