Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Suche nach einem String in allen Tabellen, Zeilen und Spalten einer DB

Dieser Code sollte es in SQL 2005 tun, aber ein paar Vorbehalte:

  1. Es ist lächerlich langsam. Ich habe es auf einer kleinen Datenbank getestet, die ich mit nur einer Handvoll Tabellen habe, und es dauerte viele Minuten, bis es fertig war. Wenn Ihre Datenbank so groß ist, dass Sie sie nicht verstehen können, ist diese wahrscheinlich sowieso unbrauchbar.

  2. Das habe ich aus dem Stegreif geschrieben. Ich habe keine Fehlerbehandlung eingebaut und es könnte einige andere Nachlässigkeiten geben, zumal ich Cursor nicht oft verwende. Zum Beispiel denke ich, dass es eine Möglichkeit gibt, den Spaltencursor zu aktualisieren, anstatt ihn jedes Mal zu schließen/freizugeben/neu zu erstellen.

Wenn Sie die Datenbank nicht verstehen können oder nicht wissen, woher etwas kommt, dann sollten Sie wahrscheinlich jemanden finden, der es versteht. Selbst wenn Sie herausfinden können, wo sich die Daten befinden, könnten sie irgendwo dupliziert sein oder es könnte andere Aspekte der Datenbank geben, die Sie nicht verstehen. Wenn niemand in Ihrem Unternehmen die Datenbank versteht, sind Sie in einem ziemlich großen Schlamassel.

DECLARE
    @search_string  VARCHAR(100),
    @table_name     SYSNAME,
    @table_schema   SYSNAME,
    @column_name    SYSNAME,
    @sql_string     VARCHAR(2000)

SET @search_string = 'Test'

DECLARE tables_cur CURSOR FOR SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'

OPEN tables_cur

FETCH NEXT FROM tables_cur INTO @table_schema, @table_name

WHILE (@@FETCH_STATUS = 0)
BEGIN
    DECLARE columns_cur CURSOR FOR SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @table_schema AND TABLE_NAME = @table_name AND COLLATION_NAME IS NOT NULL  -- Only strings have this and they always have it

    OPEN columns_cur

    FETCH NEXT FROM columns_cur INTO @column_name
    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        SET @sql_string = 'IF EXISTS (SELECT * FROM ' + QUOTENAME(@table_schema) + '.' + QUOTENAME(@table_name) + ' WHERE ' + QUOTENAME(@column_name) + ' LIKE ''%' + @search_string + '%'') PRINT ''' + QUOTENAME(@table_schema) + '.' + QUOTENAME(@table_name) + ', ' + QUOTENAME(@column_name) + ''''

        EXECUTE(@sql_string)

        FETCH NEXT FROM columns_cur INTO @column_name
    END

    CLOSE columns_cur

    DEALLOCATE columns_cur

    FETCH NEXT FROM tables_cur INTO @table_schema, @table_name
END

CLOSE tables_cur

DEALLOCATE tables_cur