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

SQL: поиск строки в каждом столбце varchar в базе данных

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

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

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

4b9b3361

Ответ 1

Используя найденную технику здесь, следующий script генерирует столбцы SELECT для всех ((n) var) char в данной базе данных. Скопируйте/вставьте результат, удалите последний "союз" и выполните. Вам нужно будет заменить 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');

Ответ 2

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

Ответ 3

Вы можете использовать курсор и представления 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 и сделать одно большое обновление в конце, но эй, что ваши предпочтения.

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

Ответ 4

Версия SQL Server 2000 версии script выше (от 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'); 

Ответ 5

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

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

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

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

-----------------------------------------------------------------------------------------------------
-- 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

Приветствия

Ответ 6

Я включил схему в версию 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');

Ответ 7

select column_name from information_schema.columns 
    where table_name ='magazines' and DATA_TYPE IN ('CHAR', 'NCHAR', 'VARCHAR', 'NVARCHAR');

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