简体   繁体   English

SQL:在数据库的每个varchar列中搜索字符串

[英]SQL: search for a string in every varchar column in a database

I have a database where a misspelled string appears in various places in different tables. 我有一个数据库,其中拼写错误的字符串出现在不同表中的不同位置。 Is there a SQL query that I can use to search for this string in every possible varchar/text column in the database? 是否有SQL查询可用于在数据库中的每个可能的varchar / text列中搜索此字符串?

I was thinking of trying to use the information_schema views somehow to create dynamic queries, but I'm not sure if that will work, or if there's a better way. 我正在考虑尝试以某种方式使用information_schema视图来创建动态查询,但我不确定这是否有效,或者是否有更好的方法。

I'm using MS SQL Server if that helps. 如果有帮助,我正在使用MS SQL Server。

Using the technique found here the following script generates SELECT's for all ((n)var)char columns in the given database. 使用此处的技术,以下脚本为给定数据库中的所有((n)var)char列生成SELECT。 Copy/paste the output, remove the very last 'union' and execute.. You'll need to replace MISSPELLING HERE with the string you're looking for. 复制/粘贴输出,删除最后一个'union'并执行..你需要用你正在寻找的字符串替换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');

Using queries for this will make this more complex than really needed. 使用查询会使这比实际需要的更复杂。 Why not consider some of the free SQL Search tools that exist out there. 为什么不考虑一些存在的免费SQL搜索工具。 ApexSQL has ApexSQL Search , and there is also SQL Search from Red-Gate. ApexSQL有ApexSQL搜索 ,还有Red-Gate的SQL搜索 Both of these will get the job done easily. 这两项都可以轻松完成工作。

You could use a cursor and the sys.tables/sys.columns views to go through them. 您可以使用游标和sys.tables / sys.columns视图来完成它们。 Give me a minute, and I'll give you the code. 给我一点时间,我会给你代码。

Update: Here you are: 更新:你在这里:

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

This will get you everything you need. 这将为您提供所需的一切。 It grabs the columns that are varchar, nvarchar, text, and ntext from your database, cycle through the columns and update each one. 它从数据库中获取varchar,nvarchar,text和ntext的列,循环遍历列并更新每个列。

Of course, you could also do this to create a concatenated SQL statement and do one big update at the end, but hey, that's your preference. 当然,你也可以这样做来创建一个连接的SQL语句并在最后做一个大的更新,但是,嘿,这是你的偏好。

And for the record, I don't like cursors, but since we're dealing with a few columns and not millions of rows, I'm okay with this one. 而且为了记录,我不喜欢游标,但是因为我们处理的是几列而不是数百万行,所以我对这个没问题。

SQL Server 2000 version of the script above (from edosoft): 上面的脚本的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'); 

If anyone should require something like this for Sybase, the following could help. 如果有人应该为Sybase要求这样的东西,以下内容可能有所帮助。

I have created the following script, where the code prints out all TableNames, ColumnNames containing the search string. 我创建了以下脚本,其中代码打印出包含搜索字符串的所有TableNames,ColumnNames。

Not performance optimised, using a cursor to loop through the DB columns, so it might take a while to run this on a big DB (depending on size, number of tables/cols etc.) 没有性能优化,使用游标循环遍历数据库列,因此可能需要一段时间才能在大数据库上运行(取决于大小,表/列数等)

However, I think it's a nice utility to search for a string in a DB. 但是,我认为在数据库中搜索字符串是一个很好的实用工具。

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

Cheers 干杯

I included the schema to edosoft's version. 我将架构包含在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');
select column_name from information_schema.columns 
    where table_name ='magazines' and DATA_TYPE IN ('CHAR', 'NCHAR', 'VARCHAR', 'NVARCHAR');

hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM