Подтвердить что ты не робот

Как найти строку внутри всей базы данных?

У меня есть одна конкретная строка, например, "123abcd", но я не знаю имя таблицы или даже имя столбца внутри таблицы в моей базе данных SQL Server. Я хочу найти его с помощью select и показать все столбцы связанной строки, поэтому мне было интересно что-то вроде:

select * from Database.dbo.* where * like  '%123abcd%'

По понятным причинам он не работает, но есть простой способ создать оператор select, чтобы сделать что-то вроде этого?

4b9b3361

Ответ 1

Это будет работать:

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;

Однако пара предупреждений. Во-первых, это возмутительно медленно и не оптимизировано. Все значения преобразуются в nvarchar просто так, что их можно сравнивать без ошибок. Вы можете столкнуться с проблемами со значениями, такими как datetime, не преобразовываясь, как ожидалось, и, следовательно, не совпадать, когда они должны быть (ложные негативы).

WHERE (0 = 1) нужно сделать предложение OR проще. Если нет совпадений, вы не получите никаких строк назад.

Ответ 2

Вот несколько бесплатных инструментов, которые можно использовать для этого. Оба работают как дополнения SSMS.

ApexSQL Search - 100% бесплатно - выполняет поиск как схемы, так и данных в таблицах. Имеет пару более полезных параметров, таких как отслеживание зависимостей...

Пакет инструментов SSMS - бесплатный для всех версий, кроме SQL 2012 - не выглядит таким передовым, как предыдущий, но имеет много других интересных функций.

Ответ 3

Думаю, у вас есть варианты:

  • Создайте динамический SQL с помощью sys.tables и sys.columns для выполнения поиска (пример здесь).

  • Используйте любую программу, которая имеет эту функцию. Примером этого является SQL Workbench (бесплатно).

Ответ 4

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 [email protected]
 set @stmtquery ='select top 1  ' + '[' [email protected]+']' + ' from ' + '['[email protected]+']' + ' where ' + '['[email protected]+']' + ' like ' + '''%' + @string + '%'''
 insert into @tmp(name) exec(@stmtquery)
 if @@rowcount >0
 insert into #tablelist values(@tablename,@columnname)
 set @[email protected] +1
end
select * from #tablelist
end

Ответ 5

В оракуле вы можете использовать следующую команду sql для генерации необходимых вам команд sql:

select 
     "select * "
     " from "||table_name||
     " where "||column_name||" like '%123abcd%' ;" as sql_command
from user_tab_columns
where data_type='VARCHAR2';

Ответ 6

Я обычно использую information_Schema.columns и information_schema.tables, хотя, как и @yuck, sys.tables и sys.columns короче для ввода.

В цикле объедините эти

@sql = @sql + 'select' + column_name + 
' from ' + table_name + 
' where ' + column_name ' like ''%''+value+''%' UNION

Затем выполните полученный sql.

Ответ 7

SQL Locator (бесплатно) отлично поработал у меня. Он поставляется с множеством опций и довольно прост в использовании.

Ответ 8

Common Resource Grep (crgrep) будет искать соответствия строк в таблицах/столбцах по имени или контенту и поддерживает несколько БД, включая SQLServer, Oracle и другие. Полный дикий кардинг и другие полезные опции.

Это openource (я автор).

http://sourceforge.net/projects/crgrep/

Ответ 9

Извините за поздний ответ, но у меня тоже был этот вопрос, и я решил его решить, используя другой подход, который, вероятно, более общий для всех баз данных.

  • создать дамп базы данных.
  • Оттуда вы сможете открыть файл в текстовом редакторе и найти нужную строку.

Ответ 10

Вот решение на основе курсора

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