我有一个数据库,其中拼写错误的字符串出现在不同表格的不同位置。是否有SQL查询可用于在数据库中的每个可能的varchar / text列中搜索此字符串?
我正在考虑尝试以某种方式使用information_schema视图来创建动态查询,但我不确定这是否有效,或者是否有更好的方法。
如果有帮助,我正在使用MS SQL Server。
答案 0 :(得分:23)
使用找到的here技术,以下脚本为给定数据库中的所有((n)var)char列生成SELECT。复制/粘贴输出,删除最后一个'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');
答案 1 :(得分:7)
使用查询会使这比实际需要的更复杂。为什么不考虑一些存在的免费SQL搜索工具。 ApexSQL有ApexSQL Search,Red-Gate也有SQL Search。这两项都可以轻松完成工作。
答案 2 :(得分:4)
您可以使用游标和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语句,并在最后做一个大的更新,但是,嘿,这是你的偏好。
为了记录,我不喜欢游标,但由于我们处理的是几列而不是数百万行,所以我对这一行没问题。
答案 3 :(得分:1)
上面脚本的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');
答案 4 :(得分:0)
如果有人要求Sybase提供类似的功能,以下内容可能有所帮助。
我创建了以下脚本,其中代码打印出包含搜索字符串的所有TableNames,ColumnNames。
没有性能优化,使用游标循环遍历数据库列,因此在大数据库上运行它可能需要一段时间(取决于大小,表/列数等)。
但是,我认为在数据库中搜索字符串是一个很好的实用工具。
-----------------------------------------------------------------------------------------------------
-- 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
干杯
答案 5 :(得分:0)
我将架构包含在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');
答案 6 :(得分:-1)
select column_name from information_schema.columns
where table_name ='magazines' and DATA_TYPE IN ('CHAR', 'NCHAR', 'VARCHAR', 'NVARCHAR');
希望有所帮助