SQL: busca una cadena en cada columna varchar en una database

Tengo una database donde aparece una cadena mal escrita en varios lugares en diferentes tablas. ¿Existe una consulta SQL que pueda usar para search esta cadena en todas las columnas de varchar / text posibles en la database?

Estaba pensando en intentar usar las vistas de information_schema de alguna manera para crear consultas dinámicas, pero no estoy seguro de si eso funcionará, o si hay una mejor manera.

Estoy usando MS SQL Server si eso ayuda.

Usando la técnica que se encuentra aquí, el siguiente script genera SELECT para todas las columnas ((n) var) char en la database dada. Copia / pega la salida, elimina la última 'unión' y ejecuta .. Tendrás que replace MISSPELLING HERE con la cadena que estás buscando.

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'); 

El uso de consultas para esto hará que esto sea más complejo de lo que realmente se necesita. ¿Por qué no considerar algunas de las herramientas gratuitas de búsqueda SQL que existen? ApexSQL tiene ApexSQL Search , y también SQL Search de Red-Gate. Ambos harán el trabajo fácilmente.

Puede usar un cursor y las vistas sys.tables / sys.columns para verlas. Dame un minuto, y te daré el código.

Actualización: Aquí estás:

 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 

Esto te dará todo lo que necesitas. Captura las columnas que son varchar, nvarchar, text y ntext de su database, recorre las columnas y actualiza cada una.

Por supuesto, también podría hacer esto para crear una statement SQL concatenada y hacer una gran actualización al final, pero bueno, esa es su preference.

Y para que conste, no me gustan los cursores, pero como estamos lidiando con unas pocas columnas y no con millones de filas, estoy de acuerdo con esta.

Versión de SQL Server 2000 del script anterior (desde 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'); 

Si alguien necesita algo como esto para Sybase, lo siguiente podría ayudar.

He creado el siguiente script, donde el código imprime todos los TableNames, ColumnNames que contienen la cadena de búsqueda.

No se optimizó el performance, utilizando un cursor para recorrer las columnas de DB, por lo que podría llevar un time ejecutarlo en una gran database (dependiendo del tamaño, el número de tablas / columnas, etc.)

Sin embargo, creo que es una buena utilidad search una cadena en un 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 

Aclamaciones

Incluí el esquema a la versión de 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'); 

Espero eso ayude