2012-10-10 29 views
13

Mam ogromny schemat z kilkoma setkami tabel i kilkoma tysiącami kolumn. Wiedziałbym, że konkretny adres IP jest przechowywany w tej bazie danych w kilku miejscach, ale nie jestem pewien, w której tabeli lub kolumnach jest przechowywany. Zasadniczo, staram się znaleźć wszędzie, że to Adres IP jest przechowywany w DB, więc mogę zaktualizować go do nowej wartości we wszystkich tych miejscach.Jak przeszukać wszystkie pola tekstowe w bazie danych dla niektórych podłańcuchów przy pomocy T-SQL

Oto moje pierwsze pęknięcie w instrukcji T-SQL, aby wydrukować nazwę tabeli i kolumny oraz wartość dla każdej kolumny tekstowej w bazie danych zawierającej podciąg 10.15.13.

To działa, w pewnym sensie. Problem polega na tym, że gdy wykonuję go w Management Studio, wywołanie sp_executesql spowoduje zwrócenie wszystkich pustych wyników z każdego zapytania, które niczego nie zwróci (tj. Kolumna nie ma żadnych rekordów z tym podciąganiem) i wypełnia okno wyników na maksa, a potem nie widzę, czy coś zostało wydrukowane.

Czy istnieje lepszy sposób napisania tego zapytania? Czy mogę uruchomić go w inny sposób, tak aby pokazywał mi tylko tabele i kolumny, w których ten podciąg?

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 

Chciałbym zobaczyć wyniki coś takiego, gdzie pokazuje tabela/kolumnę że podciąg było znaleźć, i pełną wartość w tej kolumnie ...

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

etc.

+0

Twoje zamknięcie. Porównaj swoje z tym przykładem: [Wyszukiwanie i znajdowanie wartości ciągu we wszystkich kolumnach tabeli SQL Server] (http://www.mssqltips.com/sqlservertip/1522/searching-and-finding-a-string-value-in -all-columns-in-a-sql-server-table /) – Jeremy

+0

Niesamowite dzięki! Właściwie nie użyłem tego rozwiązania z linku, ponieważ służy ono do przeszukiwania pojedynczej tabeli na raz, ale miało inne łącze do kompletnego rozwiązania do przeszukiwania wszystkich tabel w bazie danych; dokładnie to, czego potrzebowałem. http://vyaskn.tripod.com/search_all_columns_in_all_tables.htm Proszę zaksięgować to jako odpowiedź, a ja oznaczyłem to jako poprawne! – Jim

+0

Dołączyłem odpowiedź, a także link, do którego odnosiłeś się w odniesieniu do potomności. Dzięki! – Jeremy

Odpowiedz

24

Jesteś blisko. Porównać je z tym przykładzie: Searching and finding a string value in all columns in a SQL Server table

Powyższy link jest do przeszukiwania pojedynczej tabeli, jednak tutaj jest inny link, który zawiera wszystkie tabele: How to search all columns of all tables in a database for a keyword?

EDIT: Na wszelki wypadek link kiedykolwiek idzie źle, oto rozwiązanie z tego linku ...

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

Uwaga: Jako komentarz sugeruje we fragmencie kodu, który został przetestowany przy użyciu starszych wersji programu SQL Server. To może nie działać na SQL Server 2012.

+0

-1 Otrzymuję następujący błąd w SQL Server 2012 "Msg 217, Poziom 16, Stan 1, Procedura Znajdź wszystkie tablice, Linia 54 Maksymalna procedura składowana, funkcja, wyzwalacz lub poziom zagnieżdżenia widoku przekroczony (limit 32)." – codemonkeh

+0

codemonkeh, należy pamiętać o dodawaniu instrukcji drop storedrocrochedure i tabel tymczasowych po każdym wykonaniu lub przed wykonaniem. – Munawar

+0

uzyskać następujący błąd w SQL Server 2012 "Msg 217, Poziom 16, Stan 1, Procedura SearchAllTables, Linia 54 Maksymalna procedura składowana, funkcja, wyzwalacz lub poziom zagnieżdżenia widoku przekroczony (limit 32) .Taki sam błąd – Jahangeer

0

spróbować tego nie daje błąd limitu przekraczać 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 

Nadzieja pomaga

3

Wybrany odpowiedź jest genialny, ale gdy znalazłem wielokrotne używanie wyników było błędne, więc dodałem trochę czystego, aby można było go ponownie uruchomić z dokładnymi wynikami:

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