2013-04-02 5 views
118

Esiste un modo per cercare una stringa in tutte le tabelle di un database in SQL Server Management Studio 2008?Trova una stringa cercando tutte le tabelle in SQL Server Management Studio 2008

Voglio cercare stringa dire john. Il risultato dovrebbe mostrare le tabelle e la loro riga corrispondente che contengono john.

+0

possibile duplicato di [ricerca tutte le tabelle, tutte le colonne per uno specifico valore di SQL Server] (http: // StackOverflow .com/questions/1796506/search-all-tables-all-columns-per-a-specific-value-sql-server) –

+2

possibile duplicato di [Come trovare un valore in un database di SQL Server?] (http : // StackOverflow.it/questions/436351/how-do-i-find-a-value-anywhere-in-a-sql-server-database) –

+0

phpmyadmin consenti questo molto semplicemente – Matoeil

risposta

199

prega di provare la procedura per cercare tutte le colonne di tutte le tabelle per una determinata stringa di ricerca:

CREATE 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', 'int', 'decimal') 
        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 
+0

+1 Grazie mille :) –

+0

Siete i benvenuti :) – TechDo

+1

Guarda la risposta qui sotto per il codice sql server 2012 – Rafi

36

un po 'tardi ma spero utile.

Perché non provare alcuni degli strumenti di terze parti che possono essere integrati in SSMS.

Ho lavorato con ApexSQL Search (100% gratuito) con un buon successo per la ricerca di schemi e dati e c'è anche SSMS tools pack che ha questa funzione (non gratuito per SQL 2012 ma abbastanza economico).

La procedura memorizzata sopra è davvero eccezionale; è solo che questo è molto più conveniente secondo me. Inoltre, sarebbe necessario alcune lievi modifiche, se si desidera effettuare la ricerca per le colonne datetime o colonne GUID e così ...

+1

'ApexSQL Search' è un'aggiunta eccezionale a Microsoft SQL Search Management Studio! Grazie! – TranslucentCloud

23

Per aggiornare TechDo 's risposta per SQL Server 2012. È necessario modificare: 'FROM ' + @TableName + ' (NOLOCK) 'perFROM ' + @TableName + 'WITH (NOLOCK) ' +

Altri saggi si otterrà il seguente errore: Deprecated feature 'Table hint without WITH' is not supported in this version of SQL Server.

riportano di seguito le completa stored procedure aggiornamento:

CREATE 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', 'int', 'decimal') 
        AND QUOTENAME(COLUMN_NAME) > @ColumnName 
      ) 

      IF @ColumnName IS NOT NULL 

      BEGIN 
       INSERT INTO #Results 
       EXEC 
       (
        'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
        FROM ' + @TableName + 'WITH (NOLOCK) ' + 
        ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
       ) 
      END 
     END  
    END 

    SELECT ColumnName, ColumnValue FROM #Results 
END 
+0

manca una "END" alla fine dell'SP. Non posso modificarlo :( – Atlasmaybe

78

Se sei come me e hai determinate restrizioni in un ambiente di produzione, potresti voler utilizzare una variabile di tabella anziché una tabella temporanea e una query ad-hoc piuttosto che una procedura di creazione.

Ovviamente, a seconda dell'istanza del server SQL, deve supportare le variabili di tabella.

Ho anche aggiunto una dichiarazione USE per restringere il campo di ricerca

USE DATABASE_NAME 
DECLARE @SearchStr nvarchar(100) = 'SEARCH_TEXT' 
DECLARE @Results TABLE (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', 'int', 'decimal') 
       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 
+4

Impressionante, ho aggiunto "PRINT @TableName + '.' + @ColumnName" alla riga 53, così ho potuto ottenere uno stato mentre funzionava attraverso il mio grande database, ma questo è molto utile – ProVega

+1

Questo ha funzionato perfettamente! loggato solo per svenderlo Grazie – taylorsabell

+0

Questo è d'oro! – pjdupreez

1

ho scritto una SP per il presente, che restituisce i risultati della ricerca in forma del nome tabella, i nomi delle colonne in cui la stringa di ricerca per parole chiave è stato trovato così come le ricerche nelle file corrispondenti come mostrato nella schermata di seguito.

Sample Search Result

questo potrebbe non essere la soluzione più efficiente, ma si può sempre modificare e utilizzare in base alle proprie necessità.

IF OBJECT_ID('sp_KeywordSearch', 'P') IS NOT NULL 
    DROP PROC sp_KeywordSearch 
GO 

CREATE PROCEDURE sp_KeywordSearch @KeyWord NVARCHAR(100) 
AS 
BEGIN 
    DECLARE @Result TABLE 
     (TableName NVARCHAR(300), 
     ColumnName NVARCHAR(MAX)) 

    DECLARE @Sql NVARCHAR(MAX), 
     @TableName NVARCHAR(300), 
     @ColumnName NVARCHAR(300), 
     @Count INT 

    DECLARE @tableCursor CURSOR 

    SET @tableCursor = CURSOR LOCAL SCROLL FOR 
    SELECT N'SELECT @Count = COUNT(1) FROM [dbo].[' + T.TABLE_NAME + '] WITH (NOLOCK) WHERE CAST([' + C.COLUMN_NAME + 
      '] AS NVARCHAR(MAX)) LIKE ''%' + @KeyWord + N'%''', 
      T.TABLE_NAME, 
      C.COLUMN_NAME 
    FROM INFORMATION_SCHEMA.TABLES AS T WITH (NOLOCK) 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS AS C WITH (NOLOCK) 
    ON  T.TABLE_SCHEMA = C.TABLE_SCHEMA AND 
      T.TABLE_NAME = C.TABLE_NAME 
    WHERE T.TABLE_TYPE = 'BASE TABLE' AND 
      C.TABLE_SCHEMA = 'dbo' AND 
      C.DATA_TYPE NOT IN ('image', 'timestamp') 

    OPEN @tableCursor 
    FETCH NEXT FROM @tableCursor INTO @Sql, @TableName, @ColumnName 

    WHILE (@@FETCH_STATUS = 0) 
    BEGIN 
     SET @Count = 0 

     EXEC sys.sp_executesql 
      @Sql, 
      N'@Count INT OUTPUT', 
      @Count OUTPUT 

     IF @Count > 0 
     BEGIN 
      INSERT INTO @Result 
        (TableName, ColumnName) 
      VALUES (@TableName, @ColumnName) 
     END 

     FETCH NEXT FROM @tableCursor INTO @Sql, @TableName, @ColumnName 
    END 

    CLOSE @tableCursor 
    DEALLOCATE @tableCursor 

    SET @tableCursor = CURSOR LOCAL SCROLL FOR 
    SELECT SUBSTRING(TB.Sql, 1, LEN(TB.Sql) - 3) AS Sql, TB.TableName, SUBSTRING(TB.Columns, 1, LEN(TB.Columns) - 1) AS Columns 
    FROM (SELECT R.TableName, (SELECT R2.ColumnName + ', ' FROM @Result AS R2 WHERE R.TableName = R2.TableName FOR XML PATH('')) AS Columns, 
        'SELECT * FROM ' + R.TableName + ' WITH (NOLOCK) WHERE ' + 
        (SELECT 'CAST(' + R2.ColumnName + ' AS NVARCHAR(MAX)) LIKE ''%' + @KeyWord + '%'' OR ' 
        FROM @Result AS R2 
        WHERE R.TableName = R2.TableName 
        FOR 
        XML PATH('')) AS Sql 
      FROM @Result AS R 
      GROUP BY R.TableName) TB 
    ORDER BY TB.Sql 

    OPEN @tableCursor 
    FETCH NEXT FROM @tableCursor INTO @Sql, @TableName, @ColumnName 

    WHILE (@@FETCH_STATUS = 0) 
    BEGIN 
     PRINT @Sql 
     SELECT @TableName AS [Table], 
       @ColumnName AS Columns 
     EXEC(@Sql) 

     FETCH NEXT FROM @tableCursor INTO @Sql, @TableName, @ColumnName 
    END 

    CLOSE @tableCursor 
    DEALLOCATE @tableCursor 

END 
2

Un po 'in ritardo, ma si può facilmente trovare una stringa con questa query

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

SET @search_string = 'StringtoSearch' 

DECLARE tables_cur CURSOR FOR SELECT ss.name +'.'+ so.name [name], object_id FROM sys.objects so INNER JOIN sys.schemas ss ON so.schema_id = ss.schema_id WHERE type = 'U' 

OPEN tables_cur 

FETCH NEXT FROM tables_cur INTO @table_name, @table_id 

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    DECLARE columns_cur CURSOR FOR SELECT name FROM sys.columns WHERE object_id = @table_id 
     AND system_type_id IN (167, 175, 231, 239) 

    OPEN columns_cur 

    FETCH NEXT FROM columns_cur INTO @column_name 
     WHILE (@@FETCH_STATUS = 0) 
     BEGIN 
      SET @sql_string = 'IF EXISTS (SELECT * FROM ' + @table_name + ' WHERE [' + @column_name + '] 
      LIKE ''%' + @search_string + '%'') PRINT ''' + @table_name + ', ' + @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_name, @table_id 
END 

CLOSE tables_cur 
DEALLOCATE tables_cur 
+0

Questo script fallisce quando lo schema di una tabella non è "dbo" sfortunatamente la maggior parte delle tabelle in essere DB hanno schemi diversi. Funziona bene per la coppia di "dbo" "quelli – rob

+0

Appena modificato il cursore iniziale su INNER JOIN sulla tabella degli schemi in modo che ora abbia lo schema nel nome della tabella quando lo si usa. – rob

+0

Ho anche aggiunto 99 (ntext) all'elenco di system_types da cercare come attualmente ignora tutti i campi xml. 'AND system_type_id IN (167, 175, 231, 239, 99)' – rob

Problemi correlati