none
Suche in kompletter Datenbank RRS feed

  • Frage

  • Hi Leute!

    Ich arbeite an einer Abfrage, welche mir aus der GESAMTEN Datenbank einen Wert sucht.

    Leider bin ich kein Profi, deswegen muss ich mich nun an euch wenden ;)

    (Ich weiß, man könnte hier in diesem Beispiel mit Cursern arbeiten und das würde vielleicht vieles vereinfachen, doch ich habe die Curser noch nicht ganze verstanden und wollte es eben "auf meine Art" machen...)

    Ich hab dazu den folgenden Code geschrieben:

    WHILE @i <= @lTables
    BEGIN
       DECLARE @TableName varchar(50) = (
                           SELECT TOP 1 TABLE_NAME  
                           FROM (SELECT TOP (@i) TABLE_NAME 
                           FROM INFORMATION_SCHEMA.TABLES 
                           ORDER BY TABLE_NAME) a 
                  ORDER BY TABLE_NAME DESC)
       DECLARE @lColumns int = (
                            SELECT COUNT(*) 
                            FROM INFORMATION_SCHEMA.COLUMNS
                            WHERE TABLE_NAME = @TableName)
    
       WHILE @j <= @lColumns
       BEGIN
          SELECT *
          FROM   (SELECT TOP 1 * 
                  FROM (SELECT TOP (@i) * 
                        FROM INFORMATION_SCHEMA.TABLES 
                        ORDER BY TABLE_NAME) t 
                  ORDER BY TABLE_NAME DESC)
          WHERE  CAST((SELECT TOP 1 * 
                       FROM (
                             SELECT TOP (@j) COLUMN_NAME 
                             FROM INFORMATION_SCHEMA.COLUMNS 
                             WHERE TABLE_NAME = @TableName 
                             ORDER BY COLUMN_NAME) c 
                       ORDER BY COLUMN_NAME DESC) 
                       AS VARCHAR(max))
    	     = @Suchbegriff;
           SELECT @j = @j + 1;
        END
        SELECT @i = @i + 1;
    END

    Was mache ich hier?

    Das Prinzip ist einfach: ich gehe mit einer Schleife durch alle Tabellen, pro Tabelle ich mit einer Schleife nocheinmal durch alle Spalten, um überall nach dem Suchbegriff zu sehen.

    Nur das Problem: Ich bekomme die Fehlermeldung "Meldung 156, Ebene 15, Status 1, Zeile 19 Falsche Syntax in der Nähe des WHERE-Schlüsselworts." und im Code dann noch "Erwartet wird AS, ID oder QUOTED_ID".

    Nur kann ich damit nichts anfangen...jemand von euch vielleicht eine Idee wie man das Lösen könnte? :D

    PS: Ich hoffe der Code ist lesbar ^^

    Freitag, 17. Juni 2016 12:22

Antworten

  • Hallo!

    Schau Dir mal diesen alten Code von mir an. Ich hoffe, der ist noch brauchbar.

    /* Hier gibt man die Datenbank an, die gescannt werden soll */
    /* Der Suchstring ist weiter unten versteckt                */
    use pubs
    Declare @cmd varchar(500)
    
    Set Nocount On
    Declare @Anzahl			int,
    	@Fehler			int,
    	@Fehler_Gesamt		int,
    	@Fehlertext		varchar(255),
    	@Tabelle		sysname,
    	@Spalte			sysname
    
    /* Vorbelegen der Variablen zur Fehlerverarbeitung und Rückgabe */
    Set @Fehlertext 	= 'Die Datenbank wurden fehlerfrei gescannt!'
    Set @Fehler 		= 0
    Set @Fehler_Gesamt	= 0
    
    /* Eine kleine Hilfstabelle um unnötige Ausgaben zu umgehen */
    create Table MyScan (Anzahl Int)
    Set @Fehler = @@error
    If @Fehler <> 0
       begin
    	set @Fehlertext = 'Fehler bei Create MyScan!'
    	set @Fehler_Gesamt = 1
       end
    
    
    /* Hier wird der Suchstring angegeben                                       */
    /* gesucht wird nur in Feldern, die char, varchar oder nchar, nvarchar sind */
    Declare Datenbank_Scan_Cursor INSENSITIVE CURSOR for 
    select  'Insert into MyScan (Anzahl) Select count(*) from [' + Table_Schema
    +'].['+Table_Name +'] where [' + Column_Name + ']=''Johnson''', Table_Name,
    Column_Name
    from INFORMATION_SCHEMA.COLUMNS
    where data_type like '%Char'
    order by Table_Name, Column_Name
    
    /* Um nach Zahlen zu suchen, könnte dieser Teil des Skripts so aussehen:
    Declare Datenbank_Scan_Cursor INSENSITIVE CURSOR for 
    select  'Insert into MyScan (Anzahl) Select count(*) from [' + Table_Schema
    + '].['+ Table_Name + '] where [' + Column_Name + ']= 6.70' , Table_Name,
    Column_Name
    from INFORMATION_SCHEMA.COLUMNS
    where data_type in ('decimal', 'real', 'float', 'money')
    order by Table_Name, Column_Name
    */
    
    
    		
    /* Cursor öffnen und verarbeiten */
    OPEN Datenbank_Scan_Cursor
    Set @Fehler = @@error
    If @Fehler <> 0
       begin
    	set @Fehlertext = 'Fehler bei Open Cursor!'
    	set @Fehler_Gesamt = 1
       end
    Else
       begin
    
    	FETCH NEXT FROM Datenbank_Scan_Cursor INTO @Cmd, @Tabelle, @Spalte
    	Set @Fehler = @@error
    	If @Fehler <> 0
    	   begin
    		set @Fehlertext = 'Fehler bei Fetch Cursor!'
    		set @Fehler_Gesamt = 1
    
    	   end
       end
    
    
    WHILE (@@fetch_status <> -1) and @Fehler_Gesamt = 0 
       BEGIN
    
    	IF (@@fetch_status <> -2)
    	   BEGIN
    		/* Jetzt wird's ernst */
    		Truncate Table MyScan
    		Exec(@cmd)
    		Set @Fehler = @@error
    		If @Fehler <> 0
    		   begin
    			set @Fehlertext = 'Fehler bei Execute!'
    			set @Fehler_Gesamt = 1
    			print @cmd
    		   end
    		Else
    		   begin
    			Select @Anzahl = Anzahl from MyScan
    			Set @Fehler = @@error
    			If @Fehler <> 0
    			   begin
    				set @Fehlertext = 'Fehler bei Lesen der Anzahl!'
    				set @Fehler_Gesamt = 1
    				print @cmd
    			   end
    			Else
    			   begin
    				If @Anzahl > 0
    					print @Tabelle + ' / ' + @Spalte
    			   end
    		   end
    
    	   END -- (@@fetch_status <> -2)
    
    	/* Hole den Namen der nächsten Spalte		*/
    	IF @Fehler_Gesamt = 0
    	   begin
    		FETCH NEXT FROM Datenbank_Scan_Cursor INTO @Cmd, @Tabelle, @Spalte
    		Set @Fehler = @@error
    		If @Fehler <> 0
    		   begin
    			set @Fehlertext = 'Fehler bei Fetch Cursor2!'
    			set @Fehler_Gesamt = 1
    		   end
    	   end
    
       END -- While
    
    DEALLOCATE Datenbank_Scan_Cursor
    Set @Fehler = @@error
    /* Diesen Fehler nur protokollieren, falls vorher kein Fehler auftrat!		*/
    If @Fehler <> 0 and @Fehler_Gesamt = 0
       begin
    	set @Fehlertext = 'Fehler bei Deallocate Cursor!'
    	set @Fehler_Gesamt = 1
       end
    
    
    Drop Table MyScan 
    Set @Fehler = @@error
    /* Diesen Fehler nur protokollieren, falls vorher kein Fehler auftrat!		*/
    If @Fehler <> 0 and @Fehler_Gesamt = 0
       begin
    	set @Fehlertext = 'Fehler bei Drop MyScan!'
    	set @Fehler_Gesamt = 1
       end
    
    /* 	Abschließende Fehlerverarbeitung			*/
    If @Fehler_Gesamt = 0
       begin
    	Print @Fehlertext
    --	Return(0)
       end
    Else
       begin
    	RaisError(@Fehlertext, 14, 1)
    --	Return(1)
       end
    GO


    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    Freitag, 17. Juni 2016 12:47

Alle Antworten

  • Hallo!

    Schau Dir mal diesen alten Code von mir an. Ich hoffe, der ist noch brauchbar.

    /* Hier gibt man die Datenbank an, die gescannt werden soll */
    /* Der Suchstring ist weiter unten versteckt                */
    use pubs
    Declare @cmd varchar(500)
    
    Set Nocount On
    Declare @Anzahl			int,
    	@Fehler			int,
    	@Fehler_Gesamt		int,
    	@Fehlertext		varchar(255),
    	@Tabelle		sysname,
    	@Spalte			sysname
    
    /* Vorbelegen der Variablen zur Fehlerverarbeitung und Rückgabe */
    Set @Fehlertext 	= 'Die Datenbank wurden fehlerfrei gescannt!'
    Set @Fehler 		= 0
    Set @Fehler_Gesamt	= 0
    
    /* Eine kleine Hilfstabelle um unnötige Ausgaben zu umgehen */
    create Table MyScan (Anzahl Int)
    Set @Fehler = @@error
    If @Fehler <> 0
       begin
    	set @Fehlertext = 'Fehler bei Create MyScan!'
    	set @Fehler_Gesamt = 1
       end
    
    
    /* Hier wird der Suchstring angegeben                                       */
    /* gesucht wird nur in Feldern, die char, varchar oder nchar, nvarchar sind */
    Declare Datenbank_Scan_Cursor INSENSITIVE CURSOR for 
    select  'Insert into MyScan (Anzahl) Select count(*) from [' + Table_Schema
    +'].['+Table_Name +'] where [' + Column_Name + ']=''Johnson''', Table_Name,
    Column_Name
    from INFORMATION_SCHEMA.COLUMNS
    where data_type like '%Char'
    order by Table_Name, Column_Name
    
    /* Um nach Zahlen zu suchen, könnte dieser Teil des Skripts so aussehen:
    Declare Datenbank_Scan_Cursor INSENSITIVE CURSOR for 
    select  'Insert into MyScan (Anzahl) Select count(*) from [' + Table_Schema
    + '].['+ Table_Name + '] where [' + Column_Name + ']= 6.70' , Table_Name,
    Column_Name
    from INFORMATION_SCHEMA.COLUMNS
    where data_type in ('decimal', 'real', 'float', 'money')
    order by Table_Name, Column_Name
    */
    
    
    		
    /* Cursor öffnen und verarbeiten */
    OPEN Datenbank_Scan_Cursor
    Set @Fehler = @@error
    If @Fehler <> 0
       begin
    	set @Fehlertext = 'Fehler bei Open Cursor!'
    	set @Fehler_Gesamt = 1
       end
    Else
       begin
    
    	FETCH NEXT FROM Datenbank_Scan_Cursor INTO @Cmd, @Tabelle, @Spalte
    	Set @Fehler = @@error
    	If @Fehler <> 0
    	   begin
    		set @Fehlertext = 'Fehler bei Fetch Cursor!'
    		set @Fehler_Gesamt = 1
    
    	   end
       end
    
    
    WHILE (@@fetch_status <> -1) and @Fehler_Gesamt = 0 
       BEGIN
    
    	IF (@@fetch_status <> -2)
    	   BEGIN
    		/* Jetzt wird's ernst */
    		Truncate Table MyScan
    		Exec(@cmd)
    		Set @Fehler = @@error
    		If @Fehler <> 0
    		   begin
    			set @Fehlertext = 'Fehler bei Execute!'
    			set @Fehler_Gesamt = 1
    			print @cmd
    		   end
    		Else
    		   begin
    			Select @Anzahl = Anzahl from MyScan
    			Set @Fehler = @@error
    			If @Fehler <> 0
    			   begin
    				set @Fehlertext = 'Fehler bei Lesen der Anzahl!'
    				set @Fehler_Gesamt = 1
    				print @cmd
    			   end
    			Else
    			   begin
    				If @Anzahl > 0
    					print @Tabelle + ' / ' + @Spalte
    			   end
    		   end
    
    	   END -- (@@fetch_status <> -2)
    
    	/* Hole den Namen der nächsten Spalte		*/
    	IF @Fehler_Gesamt = 0
    	   begin
    		FETCH NEXT FROM Datenbank_Scan_Cursor INTO @Cmd, @Tabelle, @Spalte
    		Set @Fehler = @@error
    		If @Fehler <> 0
    		   begin
    			set @Fehlertext = 'Fehler bei Fetch Cursor2!'
    			set @Fehler_Gesamt = 1
    		   end
    	   end
    
       END -- While
    
    DEALLOCATE Datenbank_Scan_Cursor
    Set @Fehler = @@error
    /* Diesen Fehler nur protokollieren, falls vorher kein Fehler auftrat!		*/
    If @Fehler <> 0 and @Fehler_Gesamt = 0
       begin
    	set @Fehlertext = 'Fehler bei Deallocate Cursor!'
    	set @Fehler_Gesamt = 1
       end
    
    
    Drop Table MyScan 
    Set @Fehler = @@error
    /* Diesen Fehler nur protokollieren, falls vorher kein Fehler auftrat!		*/
    If @Fehler <> 0 and @Fehler_Gesamt = 0
       begin
    	set @Fehlertext = 'Fehler bei Drop MyScan!'
    	set @Fehler_Gesamt = 1
       end
    
    /* 	Abschließende Fehlerverarbeitung			*/
    If @Fehler_Gesamt = 0
       begin
    	Print @Fehlertext
    --	Return(0)
       end
    Else
       begin
    	RaisError(@Fehlertext, 14, 1)
    --	Return(1)
       end
    GO


    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    Freitag, 17. Juni 2016 12:47
  • Hallo,

    auch von mir ein Code zum ausprobieren:

    --To search all columns of all tables in Pubs database for the keyword "Computer" 
    -- EXEC SearchAllTables 'Computer'
    -- GO 
    
    
    -- Search all columns of all tables in a database for a keyword
    -- complete stored procedure code: 
    
    
    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
    
    
    Schönen Abend.

    Freitag, 17. Juni 2016 17:17