SQL: поиск строки в каждом столбце varchar в базе данных - PullRequest
18 голосов
/ 07 мая 2009

У меня есть база данных, где строка с ошибкой появляется в разных местах в разных таблицах. Есть ли SQL-запрос, который я могу использовать для поиска этой строки во всех возможных столбцах varchar / text в базе данных?

Я думал о том, чтобы как-то использовать представления information_schema для создания динамических запросов, но я не уверен, сработает ли это или есть лучший способ.

Я использую MS SQL Server, если это поможет.

Ответы [ 7 ]

24 голосов
/ 07 мая 2009

Используя найденную технику здесь следующий скрипт генерирует SELECT для всех ((n) var) символов столбца в данной базе данных. Скопируйте / вставьте вывод, удалите самый последний «союз» и выполните .. Вам нужно заменить MISSPELLING HERE на строку, которую вы ищете.

select 
'select distinct ''' + tab.name + '.' + col.name 
+ '''  from [' + tab.name 
+ '] where [' + col.name + '] like ''%MISSPELLING HERE%'' union ' 
from sys.tables tab 
join sys.columns col on (tab.object_id = col.object_id)
join sys.types types on (col.system_type_id = types.system_type_id) 
where tab.type_desc ='USER_TABLE' 
and types.name IN ('CHAR', 'NCHAR', 'VARCHAR', 'NVARCHAR');
7 голосов
/ 09 февраля 2013

Использование запросов для этого сделает это более сложным, чем действительно необходимо. Почему бы не рассмотреть некоторые из существующих бесплатных инструментов поиска SQL. ApexSQL имеет ApexSQL Search , а также есть SQL Search от Red-Gate. Оба из них сделают работу легко.

4 голосов
/ 07 мая 2009

Вы можете использовать курсор и представления sys.tables / sys.columns для их просмотра. Дайте мне минуту, и я дам вам код.

Обновление: вот вы:

declare @col_name nvarchar(50)
declare @sql nvarchar(max)
declare @tbl_name nvarchar(50)
declare @old_str nvarchar(50)
declare @new_str nvarchar(50)

set @old_str = 'stakoverflow'
set @new_str = 'StackOverflow'

declare fetch_name cursor for
select 
    c.name,
    t.name
from 
    sys.columns c
    inner join sys.tables t on c.object_id = t.object_id
    inner join sys.types y on c.system_type_id = y.system_type_id
where
    y.name like '%varchar'
    or y.name like '%text'

open fetch_name

fetch next from fetch_name into @col_name, @tbl_name

while @@fetch_status = 0
begin
    set @sql = 'UPDATE ' + @tbl_name + ' SET ' + 
        @col_name + ' = replace(' + 
            @col_name + ',''' + 
            @old_str + ''',''' + 
            @new_str + ''')'

    exec sp_executesql @sql

    fetch next from fetch_name into @col_name
end

close fetch_name
deallocate fetch_name

Это даст вам все, что вам нужно. Он извлекает из базы данных столбцы varchar, nvarchar, text и ntext, циклически перебирает столбцы и обновляет каждый из них.

Конечно, вы также можете сделать это для создания составного оператора SQL и сделать одно большое обновление в конце, но, эй, это ваше предпочтение.

И для справки, я не люблю курсоры, но так как мы имеем дело с несколькими столбцами, а не миллионами строк, я в порядке с этим.

1 голос
/ 13 августа 2010

SQL Server 2000 версия сценария выше (от edosoft):

select  
'select distinct ''[' + tab.name + ']'' as TableName, ''[' + col.name + ']'' as ColumnName'
+ ' from [' + users.name + '].[' + tab.name  
+ '] where UPPER([' + col.name + ']) like ''%MISSPELLING HERE%'' union '  
from sysobjects tab  
join syscolumns col on (tab.id = col.id) 
join systypes types on (col.xtype = types.xtype)  
join sysusers users on (tab.uid = users.uid)
where tab.xtype ='U'  
and types.name IN ('char', 'nchar', 'varchar', 'nvarchar'); 
0 голосов
/ 04 июня 2015

Я включил схему в версию Edosoft.

select 
'select distinct ''[' +  SCHEMA_NAME(tab.schema_id) + '].[' + tab.name + '].[' + col.name + ']'
+ '''  from [' +  SCHEMA_NAME(tab.schema_id) + '].[' + tab.name 
+ '] where [' + col.name + '] like ''%hsapp%'' union ' 
from sys.tables tab 
join sys.columns col on (tab.object_id = col.object_id)
join sys.types types on (col.system_type_id = types.system_type_id) 
where tab.type_desc ='USER_TABLE' 
and types.name IN ('CHAR', 'NCHAR', 'VARCHAR', 'NVARCHAR');
0 голосов
/ 08 августа 2013

Если кому-то нужно что-то подобное для Sybase, может помочь следующее.

Я создал следующий скрипт, в котором код распечатывает все имена таблиц, имена столбцов, содержащие строку поиска.

Не оптимизирована производительность, использование курсора для циклического перемещения по столбцам БД, поэтому может потребоваться некоторое время для запуска этого на большой БД (в зависимости от размера, количества таблиц / столбцов и т. Д.)

Однако я думаю, что это хорошая утилита для поиска строки в БД.

-----------------------------------------------------------------------------------------------------
-- SYBASE - SCRIPT TO FIND STRING IN ANY COLUMN IN TABLE AND PRINT TableName/ColumnName TO RESULTS --
-----------------------------------------------------------------------------------------------------

-- tested on Sybase ASE 15.7

set nocount off

-- CREATE OBJECTS REQUIRED FOR SCRIPT
create table #SearchString (SearchString varchar(100))
go

-- SET SEARCH STRING
declare @search_string  varchar(100)
set @search_string = 'SEARCH_STRING'

-- WRITE SEARCH STRING TO TEMP TABLE TO STORE IT AWAY AND BE ABLE TO READ IT IN NEXT BATCH
insert into #SearchString (SearchString)
    values (@search_string)

-- GET ALL RELEVANT TABLES AND COLUMNS
insert #TabCol
    select object_name(o.id) as TableName, c.name as ColumnName
        from sysobjects o, syscolumns c 
    where o.type = 'U' -- ONLY USER TABLES
          and c.usertype in (1,2,18,19,24,25,42) -- ONLY LOOK FOR CHAR, VARCHAR, ETC.
          and c.id = o.id
          and c.name is not null
          and c.length >= datalength(@search_string)
go

-- GET TOTAL NUMBER OF RELEVANT COLUMNS
select count(*) as RelevantColumns from #TabCol
go

-- CREATE CURSOR TO LOOP THROUGH TABLES AND COLUMNS TO FIND COLUMNS CONTAINING THE SEARCH STRING
declare cur cursor for 
select TableName, ColumnName from #TabCol order by TableName, ColumnName
for read only
go

-- VARIABLE DEFINITION
declare
    @table_name     SYSNAME,
    @table_id       int,
    @column_name    SYSNAME,
    @sql_string     varchar(2000),
    @search_string  varchar(100)

-- GET SEARCH STRING FROM TABLE
select @search_string = SearchString from #SearchString

-- CURSOR INIT
open cur

fetch cur into @table_name, @column_name

-- LOOP THROUGH TABLES AND COLUMNS SEARCHING FOR SEARCH STRING AND PRINT IF FOUND
while (@@sqlstatus != 2)
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 cur into @table_name, @column_name
end
go

-- CLEAN-UP
close cur
deallocate cur

drop table #SearchString
drop table #TabCol
go

Приветствия

0 голосов
/ 09 февраля 2013
select column_name from information_schema.columns 
    where table_name ='magazines' and DATA_TYPE IN ('CHAR', 'NCHAR', 'VARCHAR', 'NVARCHAR');

надеюсь, это поможет

...