How to find a string inside a entire database?

前端 未结 9 1311
一整个雨季
一整个雨季 2020-12-13 06:04

I have one specific string, such as \"123abcd\" for example but I don\'t know the name of the table or even the name of the column inside the table on my SQL Server Database

相关标签:
9条回答
  • 2020-12-13 06:34

    In oracle you can use the following sql command to generate the sql commands you need:

    select 
         "select * "
         " from "||table_name||
         " where "||column_name||" like '%123abcd%' ;" as sql_command
    from user_tab_columns
    where data_type='VARCHAR2';
    
    0 讨论(0)
  • 2020-12-13 06:35

    SQL Locator (free) has worked great for me. It comes with a lot of options and it's fairly easy to use.

    0 讨论(0)
  • 2020-12-13 06:37
    create procedure usp_find_string(@string as varchar(1000))
    as
    begin
    declare @mincounter as int
    declare @maxcounter as int
    declare @stmtquery as varchar(1000)
    set @stmtquery=''
    create table #tmp(tablename varchar(128),columnname varchar(128),rowid int identity)
    create table #tablelist(tablename varchar(128),columnname varchar(128))
    declare @tmp table(name varchar(128))
    declare @tablename as varchar(128)
    declare @columnname as varchar(128)
    
    insert into #tmp(tablename,columnname)
    select a.name,b.name as columnname from sysobjects a
    inner join syscolumns b on a.name=object_name(b.id)
    where a.type='u'
    and b.xtype in(select xtype from systypes
        where name='text' or name='ntext' or name='varchar' or name='nvarchar' or name='char' or name='nchar')
    order by a.name
    
    select @maxcounter=max(rowid),@mincounter=min(rowid) from #tmp 
    while(@mincounter <= @maxcounter )
    begin
     select @tablename=tablename, @columnname=columnname from #tmp where rowid=@mincounter
     set @stmtquery ='select top 1  ' + '[' +@columnname+']' + ' from ' + '['+@tablename+']' + ' where ' + '['+@columnname+']' + ' like ' + '''%' + @string + '%'''
     insert into @tmp(name) exec(@stmtquery)
     if @@rowcount >0
     insert into #tablelist values(@tablename,@columnname)
     set @mincounter=@mincounter +1
    end
    select * from #tablelist
    end
    
    0 讨论(0)
  • 2020-12-13 06:44

    Here is an easy and convenient cursor based solution

    DECLARE
    @search_string  VARCHAR(100),
    @table_name     SYSNAME,
    @table_id       INT,
    @column_name    SYSNAME,
    @sql_string     VARCHAR(2000)
    
    SET @search_string = 'StringtoSearch'
    
    DECLARE tables_cur CURSOR FOR SELECT name, object_id FROM sys.objects WHERE  type = 'U'
    
    OPEN tables_cur
    
    FETCH NEXT FROM tables_cur INTO @table_name, @table_id
    
    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        DECLARE columns_cur CURSOR FOR SELECT name FROM sys.columns WHERE object_id = @table_id 
            AND system_type_id IN (167, 175, 231, 239)
    
        OPEN columns_cur
    
        FETCH NEXT FROM columns_cur INTO @column_name
            WHILE (@@FETCH_STATUS = 0)
            BEGIN
                SET @sql_string = 'IF EXISTS (SELECT * FROM ' + @table_name + ' WHERE [' + @column_name + '] 
                LIKE ''%' + @search_string + '%'') PRINT ''' + @table_name + ', ' + @column_name + ''''
    
                EXECUTE(@sql_string)
    
            FETCH NEXT FROM columns_cur INTO @column_name
            END
    
        CLOSE columns_cur
    
    DEALLOCATE columns_cur
    
    FETCH NEXT FROM tables_cur INTO @table_name, @table_id
    END
    
    CLOSE tables_cur
    DEALLOCATE tables_cur
    
    0 讨论(0)
  • 2020-12-13 06:49

    This will work:

    DECLARE @MyValue NVarChar(4000) = 'something';
    
    SELECT S.name SchemaName, T.name TableName
    INTO #T
    FROM sys.schemas S INNER JOIN
         sys.tables T ON S.schema_id = T.schema_id;
    
    WHILE (EXISTS (SELECT * FROM #T)) BEGIN
      DECLARE @SQL NVarChar(4000) = 'SELECT * FROM $$TableName WHERE (0 = 1) ';
      DECLARE @TableName NVarChar(1000) = (
        SELECT TOP 1 SchemaName + '.' + TableName FROM #T
      );
      SELECT @SQL = REPLACE(@SQL, '$$TableName', @TableName);
    
      DECLARE @Cols NVarChar(4000) = '';
    
      SELECT
        @Cols = COALESCE(@Cols + 'OR CONVERT(NVarChar(4000), ', '') + C.name + ') = CONVERT(NVarChar(4000), ''$$MyValue'') '
      FROM sys.columns C
      WHERE C.object_id = OBJECT_ID(@TableName);
    
      SELECT @Cols = REPLACE(@Cols, '$$MyValue', @MyValue);
      SELECT @SQL = @SQL + @Cols;
    
      EXECUTE(@SQL);
    
      DELETE FROM #T
      WHERE SchemaName + '.' + TableName = @TableName;
    END;
    
    DROP TABLE #T;
    

    A couple caveats, though. First, this is outrageously slow and non-optimized. All values are being converted to nvarchar simply so that they can be compared without error. You may run into problems with values like datetime not converting as expected and therefore not being matched when they should be (false negatives).

    The WHERE (0 = 1) is there to make building the OR clause easier. If there are not matches you won't get any rows back.

    0 讨论(0)
  • 2020-12-13 06:55

    Here are couple more free tools that can be used for this. Both work as SSMS addins.

    ApexSQL Search – 100% free - searches both schema and data in tables. Has couple more useful options such as dependency tracking…

    SSMS Tools pack – free for all versions except SQL 2012 – doesn’t look as advanced as previous one but has a lot of other cool features.

    0 讨论(0)
提交回复
热议问题