2012-10-10 7 views
13

Ich habe ein großes Schema mit mehreren hundert Tabellen und mehrere tausend Spalten. Ich würde wissen, dass eine bestimmte IP-Adresse in dieser Datenbank an mehreren Stellen gespeichert ist, aber ich bin mir nicht sicher, in welcher (n) Tabelle (n) oder Spalte (n) sie gespeichert ist. Grundsätzlich versuche ich überall das zu finden Die IP-Adresse wird in der DB gespeichert, so dass ich sie an all diesen Stellen auf einen neuen Wert aktualisieren kann.Wie alle Textfelder in einem DB nach einem Teilstring mit T-SQL zu suchen

Hier ist mein erster Fehler bei einer T-SQL-Anweisung, den Tabellen- und Spaltennamen sowie den Wert für jede Textspalte in der Datenbank auszugeben, in der der Teilstring 10.15.13 enthalten ist.

Nun, das funktioniert, irgendwie. Das Problem ist, wenn ich es in Management Studio ausführe, der Aufruf von sp_executesql wird tatsächlich alle leeren Ergebnisse von jeder Abfrage zurückgeben, die nichts zurückgibt (dh die Spalte hat keine Datensätze mit diesem Teilstring), und es füllt das Ergebnisfenster bis zum Maximum, und dann sehe ich nicht wirklich, ob etwas gedruckt wurde.

Gibt es eine bessere Möglichkeit, diese Abfrage zu schreiben? Oder kann ich es auf eine andere Art und Weise ausführen, so dass es mir nur die Tabellen und Spalten zeigt, wo dieser Teilstring existiert?

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 

Ich mag würde Ergebnisse, so etwas sehen, wo es die Tabelle/Spalte zeigt, dass der Teil gefunden wurde, und den vollen Wert in dieser Spalte ...

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

usw.

+0

Ihre schließen. Vergleichen Sie Ihr Beispiel mit diesem Beispiel: [Einen String-Wert in allen Spalten einer SQL Server-Tabelle suchen und finden] (http://www.mssqltips.com/sqlservertip/1522/searching-and-finding-a-string-value-in -all-columns-in-einem-sql-server-table /) – Jeremy

+0

Super Danke! Ich habe diese Lösung tatsächlich nicht von der Verknüpfung verwendet, da sie nur eine einzelne Tabelle durchsuchen kann, aber sie hatte eine andere Verknüpfung zu einer vollständigen Lösung zum Durchsuchen aller Tabellen in einer Datenbank. genau was ich brauchte. http://vyaskn.tripod.com/search_all_columns_in_all_tables.htm Bitte posten Sie dies als Antwort und ich werde es als korrekt markieren! – Jim

+0

Ich habe die Antwort und den Link, auf den Sie sich bezogen haben, in die Nachwelt eingefügt. Vielen Dank! – Jeremy

Antwort

24

Sie sind in der Nähe. Vergleichen Sie Ihnen mit diesem Beispiel: Searching and finding a string value in all columns in a SQL Server table

Der obige Link zum Suchen einer einzigen Tabelle ist jedoch hier eine andere Verbindung, die alle Tabellen enthält, ist: How to search all columns of all tables in a database for a keyword?

EDIT: Nur für den Fall der Link immer schlecht geht, hier ist die Lösung von diesem 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>' 

Hinweis: Wie der Kommentar im snippet-Code vermuten läßt, wurde es mit älteren Versionen von SQL Server getestet. Dies kann nicht auf SQL Server arbeiten 2012

+0

-1 Ich erhalte den folgenden Fehler in SQL Server 2012 "Nachricht 217, Ebene 16, Status 1, Prozedur SearchAllTables, Linie 54 Maximale Stored Procedure, Funktion, Trigger oder Ansicht Verschachtelungstiefe überschritten (Limit 32)." – codemonkeh

+0

Codemonkeh, stellen Sie sicher, nach jeder Ausführung ODER vor der Ausführung drop gespeicherte Prozedur und temporäre Tabellenanweisungen hinzuzufügen. – Munawar

+0

Erhalte den folgenden Fehler in SQL Server 2012 "Nachricht 217, Ebene 16, Status 1, Prozedur SearchAllTables, Zeile 54 Maximale Stored Procedure, Funktion, Trigger oder Ansicht Verschachtelungsebene überschritten (Limit 32). Derselbe Fehler – Jahangeer

0

versuchen, dies Es wird Sie nicht den Fehler der Grenze geben überschreiten 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 

Hoffe, dass es

3

hilft Die gewählte Antwort ist brillant, aber ich fand, wenn Bei wiederholter Verwendung waren die Ergebnisse fehlerhaft, daher fügte ich einige saubermachende hinzu, um sie mit genauen Ergebnissen wieder lauffähig zu machen:

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 
Verwandte Themen