2012-10-10 10 views
13

Ho uno schema enorme, con diverse centinaia di tabelle e diverse migliaia di colonne. Saprei che un indirizzo IP specifico è memorizzato in questo database in diversi punti, ma non sono sicuro di quale tabella (s) o colonna (s) è memorizzato. Fondamentalmente, sto cercando di trovare ovunque che questo L'indirizzo IP è memorizzato nel DB in modo da poterlo aggiornare ad un nuovo valore in tutti questi posti.Come cercare tutti i campi di testo in un DB per alcune sottostringhe con T-SQL

Ecco il mio primo tentativo in un'istruzione T-SQL per stampare il nome di tabella e colonna e il valore, per ogni colonna di testo nel database che contiene la sottostringa 10.15.13.

Ora, questo funziona, una specie di. Il problema è che quando lo eseguo in Management Studio, la chiamata a sp_executesql restituirà effettivamente tutti i risultati vuoti da ogni query che non restituisce nulla (cioè la colonna non ha alcun record con quella sottostringa) e riempie la finestra dei risultati al suo massimo, e quindi in realtà non vedo se qualcosa è stato stampato.

C'è un modo migliore per scrivere questa query? O posso eseguirlo in un modo diverso in modo che solo mi mostra le tabelle e le colonne in cui questa sottostringa esiste?

DECLARE 
    @SchemaName VARCHAR(50), 
    @TableName VARCHAR(50), 
    @ColumnName VARCHAR(50); 
BEGIN 
    DECLARE textColumns CURSOR FOR 
    SELECT s.Name, tab.Name, c.Name 
    FROM Sys.Columns c, Sys.Types t, Sys.Tables tab, Sys.Schemas s 
    WHERE s.schema_id = tab.schema_id AND tab.object_id = c.object_id AND c.user_type_id = t.user_type_id 
    AND t.Name in ('TEXT','NTEXT','VARCHAR','CHAR','NVARCHAR','NCHAR'); 

    OPEN textColumns 

    FETCH NEXT FROM textColumns 
    INTO @SchemaName, @TableName, @ColumnName 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     DECLARE @sql NVARCHAR(MAX), 
       @ParamDef NVARCHAR(MAX), 
       @result NVARCHAR(MAX);    
     SET @sql = N'SELECT ' + @ColumnName + ' FROM ' + @SchemaName + '.' + @TableName + ' WHERE ' + @ColumnName + ' LIKE ''%10.15.13%'''; 
     SET @ParamDef = N'@resultOut NVARCHAR(MAX) OUTPUT'; 

     EXEC sp_executesql @sql, @ParamDef, @resultOut = @result OUTPUT; 

     PRINT 'Column = ' + @TableName + '.' + @ColumnName + ', Value = ' + @result; 
     FETCH NEXT FROM textColumns 
     INTO @SchemaName, @TableName, @ColumnName  
    END 
    CLOSE textColumns; 
    DEALLOCATE textColumns; 
END 

mi piacerebbe vedere i risultati qualcosa come questo dove si mostra l'/ colonna della tabella che la stringa è stato trovato in, e il pieno valore in quella colonna ...

Column = SomeTable.SomeTextColumn, Value = 'https://10.15.13.210/foo' 
Column = SomeTable.SomeOtherColumn, Value = '10.15.13.210' 

etc.

+0

Il tuo vicino. Confronta il tuo con questo esempio: [Ricerca e ricerca di un valore stringa in tutte le colonne in una tabella SQL Server] (http://www.mssqltips.com/sqlservertip/1522/searching-and-finding-a-string-value-in -all-columns-in-a-sql-server-table /) – Jeremy

+0

Grazie fantastici! In realtà non ho usato questa soluzione dal collegamento perché è per cercare una singola tabella alla volta, ma aveva un altro collegamento a una soluzione completa per la ricerca di tutte le tabelle in un database; esattamente quello di cui avevo bisogno http://vyaskn.tripod.com/search_all_columns_in_all_tables.htm Per favore, postalo come risposta e lo contrassegnerò come corretto! – Jim

+0

Ho incluso la risposta e il link a cui ti riferivi per i posteri. Grazie! – Jeremy

risposta

24

Sei vicino. Confrontare la vostra con questo esempio: Searching and finding a string value in all columns in a SQL Server table

Il link qui sopra è per la ricerca di una singola tabella, ma qui è un altro link che include tutte le tabelle: How to search all columns of all tables in a database for a keyword?

EDIT: Nel caso in cui il legame mai va male, ecco la soluzione da quel link ...

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 


EXEC SearchAllTables '<yourSubstringHere>' 

Nota: Come il commento suggerisce nel frammento di codice, è stato testato con le versioni precedenti di SQL Server. Questo potrebbe non funzionare su SQL Server 2012.

+0

-1 Viene visualizzato il seguente errore in SQL Server 2012 "Msg 217, livello 16, stato 1, procedura SearchAllTables, riga 54 La stored procedure massima, la funzione, il trigger o il livello di annidamento delle visualizzazioni hanno superato (limite 32)." – codemonkeh

+0

codemonkeh, assicurati di aggiungere le istruzioni drop storedprocedure e temp table dopo ogni esecuzione OR prima dell'esecuzione. – Munawar

+0

ottiene il seguente errore in SQL Server 2012 "Messaggio 217, livello 16, stato 1, procedura SearchAllTables, riga 54 stored procedure massima, funzione, trigger o livello di nidificazione delle visualizzazioni superato (limite 32). Errore identico – Jahangeer

0

provare questo non vi darà l'errore di limite di superare 32

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



    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 

Speranza che aiuta

3

La risposta scelto è brillante, ma ho trovato quando usandolo ripetutamente i risultati sono stati errati, quindi ho aggiunto un po 'di pulizia per renderlo riproducibile con risultati accurati:

IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'SearchAllTables') 
    DROP PROC SearchAllTables 
GO 

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 
    -- Slightly modified by: Natalie Ford, 6/10/15 
    -- 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 

    TRUNCATE Table #Results 

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 

    DROP TABLE #Results 
END