2009-04-02 49 views
84

¿Hay alguna manera de buscar un valor (en mi caso es un UID del tipo char (64)) dentro de cualquier columna de cualquier tabla dentro de una base de datos MS-SQL?¿Cómo buscar un valor en cualquier columna de cualquier tabla dentro de una base de datos MS-SQL?

Estoy sentado frente a una gran base de datos sin tener idea de cómo las tablas deben estar unidas. Para averiguarlo, me gustaría enumerar todas las tablas y las columnas que contienen un cierto valor en cualquier fila. ¿Es eso posible?

Una forma podría ser simplemente volcar toda la base de datos en un archivo de texto y usar cualquier editor de texto para buscar el valor, pero esto sería puro dolor si la base de datos es demasiado grande.

+1

posible duplicado de [¿Cómo puedo encontrar un valor en cualquier lugar en una base de datos SQL Server?] (Http://stackoverflow.com/questions/436351/how-do-i-find-a-value-anywhere-in-a -sql-server-database) – LittleBobbyTables

+0

Posible duplicado de [¿Cómo puedo encontrar un valor en cualquier lugar en una base de datos SQL Server?] (http://stackoverflow.com/questions/436351/how-do-i-find-a-value -anywhere-in-a-sql-server-database) – Omar

Respuesta

102

Gracias por la pregunta, ya que este es un tema realmente útil. Voy a utilizar esto yo mismo también ahora por razones como la que propones. :-)

Cómo buscar todas las columnas de todas las tablas en una base de datos para buscar una palabra clave?

http://vyaskn.tripod.com/search_all_columns_in_all_tables.htm

Andrew

-Edit, aquí está el actual T-SQL, en el caso de enlace roto:

CREATE PROC SearchAllTables 
(
@SearchStr nvarchar(100) 
) 
AS 
BEGIN 

-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved. 
-- Purpose: To search all columns of all tables for a given search string 
-- Written by: Narayana Vyas Kondreddi 
-- Site: http://vyaskn.tripod.com 
-- Tested on: SQL Server 7.0 and SQL Server 2000 
-- Date modified: 28th July 2002 22:50 GMT 


CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630)) 

SET NOCOUNT ON 

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) 
SET @TableName = '' 
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') 

WHILE @TableName IS NOT NULL 
BEGIN 
    SET @ColumnName = '' 
    SET @TableName = 
    (
     SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) 
     FROM INFORMATION_SCHEMA.TABLES 
     WHERE  TABLE_TYPE = 'BASE TABLE' 
      AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName 
      AND OBJECTPROPERTY(
        OBJECT_ID(
         QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) 
         ), 'IsMSShipped' 
          ) = 0 
    ) 

    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) 
    BEGIN 
     SET @ColumnName = 
     (
      SELECT MIN(QUOTENAME(COLUMN_NAME)) 
      FROM INFORMATION_SCHEMA.COLUMNS 
      WHERE  TABLE_SCHEMA = PARSENAME(@TableName, 2) 
       AND TABLE_NAME = PARSENAME(@TableName, 1) 
       AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar') 
       AND QUOTENAME(COLUMN_NAME) > @ColumnName 
     ) 

     IF @ColumnName IS NOT NULL 
     BEGIN 
      INSERT INTO #Results 
      EXEC 
      (
       'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
       FROM ' + @TableName + ' (NOLOCK) ' + 
       ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
      ) 
     END 
    END 
END 

SELECT ColumnName, ColumnValue FROM #Results 
END 
+3

No funciona cuando se busca uniqueidentifier (pasado en '') – Pol

+1

¡Buen script! Usé esto para encontrar todas las columnas que tenían una dirección de correo electrónico en ellas para poder actualizarlo. Otro buen script de muestra es http://gallery.technet.microsoft.com/scriptcenter/c0c57332-8624-48c0-b4c3-5b31fe641c58. – NateJ

+0

¿Podría quizás agregar una indicación de cuánto tiempo lleva ejecutar este procedimiento? (un segundo, ¿horas?) –

9

amplié el código, ya que no me ha dicho el 'record number', y yo debemos reencontrar la misma.

CREATE PROC SearchAllTables 
(
@SearchStr nvarchar(100) 
) 
AS 
BEGIN 

-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved. 
-- Purpose: To search all columns of all tables for a given search string 
-- Written by: Narayana Vyas Kondreddi 
-- Site: http://vyaskn.tripod.com 
-- Tested on: SQL Server 7.0 and SQL Server 2000 
-- Date modified: 28th July 2002 22:50 GMT 

-- Copyright @ 2012 Gyula Kulifai. All rights reserved. 
-- Extended By: Gyula Kulifai 
-- Purpose: To put key values, to exactly determine the position of search 
-- Resources: Anatoly Lubarsky 
-- Date extension: 19th October 2012 12:24 GMT 
-- Tested on: SQL Server 10.0.5500 (SQL Server 2008 SP3) 

CREATE TABLE #Results (TableName nvarchar(370), KeyValues nvarchar(3630), ColumnName nvarchar(370), ColumnValue nvarchar(3630)) 

SET NOCOUNT ON 

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) 
    ,@TableShortName nvarchar(256) 
    ,@TableKeys nvarchar(512) 
    ,@SQL nvarchar(3830) 

SET @TableName = '' 
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') 

WHILE @TableName IS NOT NULL 
BEGIN 
    SET @ColumnName = '' 

    -- Scan Tables 
    SET @TableName = 
    (
     SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) 
     FROM INFORMATION_SCHEMA.TABLES 
     WHERE  TABLE_TYPE = 'BASE TABLE' 
      AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName 
      AND OBJECTPROPERTY(
        OBJECT_ID(
         QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) 
         ), 'IsMSShipped' 
          ) = 0 
    ) 
    Set @TableShortName=PARSENAME(@TableName, 1) 
    -- print @TableName + ';' + @TableShortName +'!' -- *** DEBUG LINE *** 

     -- LOOK Key Fields, Set Key Columns 
     SET @TableKeys='' 
     SELECT @TableKeys = @TableKeys + '''' + QUOTENAME([name]) + ': '' + CONVERT(nvarchar(250),' + [name] + ') + ''' + ',' + ''' + ' 
     FROM syscolumns 
     WHERE [id] IN (
      SELECT [id] 
      FROM sysobjects 
      WHERE [name] = @TableShortName) 
      AND colid IN (
      SELECT SIK.colid 
      FROM sysindexkeys SIK 
      JOIN sysobjects SO ON 
       SIK.[id] = SO.[id] 
      WHERE 
       SIK.indid = 1 
       AND SO.[name] = @TableShortName) 
     If @TableKeys<>'' 
      SET @TableKeys=SUBSTRING(@TableKeys,1,Len(@TableKeys)-8) 
     -- Print @TableName + ';' + @TableKeys + '!' -- *** DEBUG LINE *** 

    -- Search in Columns 
    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) 
    BEGIN 
     SET @ColumnName = 
     (
      SELECT MIN(QUOTENAME(COLUMN_NAME)) 
      FROM INFORMATION_SCHEMA.COLUMNS 
      WHERE  TABLE_SCHEMA = PARSENAME(@TableName, 2) 
       AND TABLE_NAME = PARSENAME(@TableName, 1) 
       AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar') 
       AND QUOTENAME(COLUMN_NAME) > @ColumnName 
     ) -- Set ColumnName 

     IF @ColumnName IS NOT NULL 
     BEGIN 
      SET @SQL=' 
       SELECT 
        ''' + @TableName + ''' 
        ,'[email protected]+' 
        ,''' + @ColumnName + ''' 
       ,LEFT(' + @ColumnName + ', 3630) 
       FROM ' + @TableName + ' (NOLOCK) ' + 
       ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
      --Print @SQL -- *** DEBUG LINE *** 
      INSERT INTO #Results 
       Exec (@SQL) 
     END -- IF ColumnName 
    END -- While Table and Column 
END --While Table 

SELECT TableName, KeyValues, ColumnName, ColumnValue FROM #Results 
END 
15

Tarde una, pero espero sea de utilidad ...

que tenían el mismo problema hace varios meses, pero me las arreglé para resolver esto utilizando herramientas de terceros.

Todas las herramientas mencionadas a continuación son 100% gratuitas.

He usado ApexSQL Search con éxito para buscar objetos y datos en tablas. Viene con varias otras características tales como diagramas de relación y tal ...

yo era un poco lento en grande (Base de datos de TFS 40GB) bases de datos, aunque ...

enter image description here

Aparte de esto también hay SSMS Tools pack que las ofertas muchas otras funciones que son bastante útiles aunque no estén directamente relacionadas con la búsqueda de texto.

+0

La base de datos que buscamos con la herramienta Apex tenía más de 580 tablas en ella. Cuando ejecuté la búsqueda en todas las tablas, la herramienta diría que terminó de buscar con éxito pero no encontró resultados. Cuando descubrí en qué tabla estaban mis datos y corrí solo contra esa tabla, lo encontraría. Incluso si seleccioné algunas tablas, funcionaría, pero no con las 580+ tablas. Tal vez tiene un tiempo de espera? – skinneejoe

5

Fuente: http://fullparam.wordpress.com/2012/09/07/fck-it-i-am-going-to-search-all-tables-all-collumns/

tengo una solución a partir de hace un tiempo que seguía mejorando. También busca dentro de las columnas XML si se le pide que lo haga, o busca valores enteros si proporciona una cadena de enteros solamente.

/* Reto Egeter, fullparam.wordpress.com */ 

DECLARE @SearchStrTableName nvarchar(255), @SearchStrColumnName nvarchar(255), @SearchStrColumnValue nvarchar(255), @SearchStrInXML bit, @FullRowResult bit, @FullRowResultRows int 
SET @SearchStrColumnValue = '%searchthis%' /* use LIKE syntax */ 
SET @FullRowResult = 1 
SET @FullRowResultRows = 3 
SET @SearchStrTableName = NULL /* NULL for all tables, uses LIKE syntax */ 
SET @SearchStrColumnName = NULL /* NULL for all columns, uses LIKE syntax */ 
SET @SearchStrInXML = 0 /* Searching XML data may be slow */ 

IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results 
CREATE TABLE #Results (TableName nvarchar(128), ColumnName nvarchar(128), ColumnValue nvarchar(max),ColumnType nvarchar(20)) 

SET NOCOUNT ON 

DECLARE @TableName nvarchar(256) = '',@ColumnName nvarchar(128),@ColumnType nvarchar(20), @QuotedSearchStrColumnValue nvarchar(110), @QuotedSearchStrColumnName nvarchar(110) 
SET @QuotedSearchStrColumnValue = QUOTENAME(@SearchStrColumnValue,'''') 
DECLARE @ColumnNameTable TABLE (COLUMN_NAME nvarchar(128),DATA_TYPE nvarchar(20)) 

WHILE @TableName IS NOT NULL 
BEGIN 
SET @TableName = 
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE' 
AND TABLE_NAME LIKE COALESCE(@SearchStrTableName,TABLE_NAME) 
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName 
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0 
) 
IF @TableName IS NOT NULL 
BEGIN 
DECLARE @sql VARCHAR(MAX) 
SET @sql = 'SELECT QUOTENAME(COLUMN_NAME),DATA_TYPE 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_SCHEMA = PARSENAME(''' + @TableName + ''', 2) 
AND TABLE_NAME = PARSENAME(''' + @TableName + ''', 1) 
AND DATA_TYPE IN (' + CASE WHEN ISNUMERIC(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@SearchStrColumnValue,'%',''),'_',''),'[',''),']',''),'-','')) = 1 THEN '''tinyint'',''int'',''smallint'',''bigint'',''numeric'',''decimal'',''smallmoney'',''money'',' ELSE '' END + '''char'',''varchar'',''nchar'',''nvarchar'',''timestamp'',''uniqueidentifier''' + CASE @SearchStrInXML WHEN 1 THEN ',''xml''' ELSE '' END + ') 
AND COLUMN_NAME LIKE COALESCE(' + CASE WHEN @SearchStrColumnName IS NULL THEN 'NULL' ELSE '''' + @SearchStrColumnName + '''' END + ',COLUMN_NAME)' 
INSERT INTO @ColumnNameTable 
EXEC (@sql) 
WHILE EXISTS (SELECT TOP 1 COLUMN_NAME FROM @ColumnNameTable) 
BEGIN 
PRINT @ColumnName 
SELECT TOP 1 @ColumnName = COLUMN_NAME,@ColumnType = DATA_TYPE FROM @ColumnNameTable 
SET @sql = 'SELECT ''' + @TableName + ''',''' + @ColumnName + ''',' + CASE @ColumnType WHEN 'xml' THEN 'LEFT(CAST(' + @ColumnName + ' AS nvarchar(MAX)), 4096),''' 
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ @ColumnName + '),''' 
ELSE 'LEFT(' + @ColumnName + ', 4096),''' END + @ColumnType + ''' 
FROM ' + @TableName + ' (NOLOCK) ' + 
' WHERE ' + CASE @ColumnType WHEN 'xml' THEN 'CAST(' + @ColumnName + ' AS nvarchar(MAX))' 
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ @ColumnName + ')' 
ELSE @ColumnName END + ' LIKE ' + @QuotedSearchStrColumnValue 
INSERT INTO #Results 
EXEC(@sql) 
IF @@ROWCOUNT > 0 IF @FullRowResult = 1 
BEGIN 
SET @sql = 'SELECT TOP ' + CAST(@FullRowResultRows AS VARCHAR(3)) + ' ''' + @TableName + ''' AS [TableFound],''' + @ColumnName + ''' AS [ColumnFound],''FullRow>'' AS [FullRow>],*' + 
' FROM ' + @TableName + ' (NOLOCK) ' + 
' WHERE ' + CASE @ColumnType WHEN 'xml' THEN 'CAST(' + @ColumnName + ' AS nvarchar(MAX))' 
WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ @ColumnName + ')' 
ELSE @ColumnName END + ' LIKE ' + @QuotedSearchStrColumnValue 
EXEC(@sql) 
END 
DELETE FROM @ColumnNameTable WHERE COLUMN_NAME = @ColumnName 
END 
END 
END 
SET NOCOUNT OFF 

SELECT TableName, ColumnName, ColumnValue, ColumnType, COUNT(*) AS Count FROM #Results 
GROUP BY TableName, ColumnName, ColumnValue, ColumnType 
1

he encontrado una solución bastante robusto en https://gallery.technet.microsoft.com/scriptcenter/c0c57332-8624-48c0-b4c3-5b31fe641c58, lo cual pensé que valía la pena señalar. Busca columnas de estos tipos: varchar, char, nvarchar, nchar, text. Funciona de maravilla y es compatible con la búsqueda de tablas específica, así como con múltiples términos de búsqueda.

+0

Escritura genial, definitivamente más compleja que lo que OP quería, también, muy útil + 1; – Pakk

0

Después de probar la solución de @regeter y ver que no resolvía mi problema cuando estaba buscando una clave externa/primaria para ver todas las tablas/columnas donde existe, no funcionó. Después de leer cómo falló para otro que intentó usar un identificador único, hice las modificaciones y aquí está el resultado actualizado: (funciona tanto con int, como con las guías ... verá cómo extenderlo fácilmente)

CREATE PROC [dbo].[SearchAllTables_Like] 
(
     @SearchStr nvarchar(100) 
) 
AS 
BEGIN 

-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved. 
-- Purpose: To search all columns of all tables for a given search string 
-- Written by: Narayana Vyas Kondreddi 
-- Site: http://vyaskn.tripod.com 
-- Tested on: SQL Server 7.0 and SQL Server 2000 
-- Date modified: 28th July 2002 22:50 GMT 


CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630)) 

SET NOCOUNT ON 

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) 
SET @TableName = '' 
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') 

WHILE @TableName IS NOT NULL 
BEGIN 
    SET @ColumnName = '' 
    SET @TableName = 
    (
     SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) 
     FROM INFORMATION_SCHEMA.TABLES 
     WHERE  TABLE_TYPE = 'BASE TABLE' 
      AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName 
      AND OBJECTPROPERTY(
        OBJECT_ID(
         QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) 
         ), 'IsMSShipped' 
          ) = 0 
    ) 

    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) 
    BEGIN 

     SET @ColumnName = 
     (
      SELECT MIN(QUOTENAME(COLUMN_NAME)) 
      FROM INFORMATION_SCHEMA.COLUMNS 
      WHERE  TABLE_SCHEMA = PARSENAME(@TableName, 2) 
       AND TABLE_NAME = PARSENAME(@TableName, 1) 
       AND DATA_TYPE IN ('guid', 'int', 'char', 'varchar', 'nchar', 'nvarchar') 
       AND QUOTENAME(COLUMN_NAME) > @ColumnName 
     ) 

     IF @ColumnName IS NOT NULL 
     BEGIN 
      INSERT INTO #Results 
      EXEC 
      (
       'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
       FROM ' + @TableName + ' (NOLOCK) ' + 
       ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
      ) 
     END 
    END 
END 

SELECT ColumnName, ColumnValue FROM #Results 
END 
Cuestiones relacionadas