Find a value anywhere in a database

前端 未结 18 1235
小蘑菇
小蘑菇 2020-11-22 03:52

Given a #, how do I discover in what table and column it could be found within?

I don\'t care if it\'s fast, it just needs to work.

18条回答
  •  半阙折子戏
    2020-11-22 04:00

    I optimized Allain Lalonde answer (https://stackoverflow.com/a/436676/412368). Numeric values are still supported. Should be roughly 4-5 times faster (1:03 vs 4:30), tested on a desktop with a 7GB database. http://developer.azurewebsites.net/2015/01/mssql-searchalltables/

    IF OBJECT_ID ('dbo.SearchAllTables', 'P') IS NOT NULL 
        DROP PROCEDURE dbo.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
    -- Site: http://vyaskn.tripod.com
    -- Customized and modified: 2014-01-21
    -- Tested on: SQL Server 2008 R2
    
    DECLARE @Results TABLE(ColumnName nvarchar(370), ColumnValue nvarchar(3630))
    
    SET NOCOUNT ON
    
    DECLARE @TableName nvarchar(256)
    DECLARE @ColumnName nvarchar(128)
    DECLARE @DataType nvarchar(128)
    
    DECLARE @SearchStr2 nvarchar(110)
    DECLARE @SearchDecimal decimal(38,19)
    DECLARE @Query nvarchar(4000)
    SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%', '''')
    SET @SearchDecimal = CASE WHEN ISNUMERIC(@SearchStr) = 1 THEN CONVERT(decimal(38,19), @SearchStr) ELSE NULL END
    PRINT '@SearchStr2: ' + @SearchStr2
    PRINT '@SearchDecimal: ' + CAST(@SearchDecimal AS nvarchar)
    
    SET @TableName = ''
    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))
                        DATA_TYPE
                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', 'bigint', 'tinyint', 'numeric', 'decimal')
                    AND QUOTENAME(COLUMN_NAME) > @ColumnName
            )
            SET @DataType =
            (
                SELECT DATA_TYPE
                FROM    INFORMATION_SCHEMA.COLUMNS
                WHERE       TABLE_SCHEMA    = PARSENAME(@TableName, 2)
                    AND TABLE_NAME  = PARSENAME(@TableName, 1)
                    AND QUOTENAME(COLUMN_NAME) = @ColumnName
            )
            PRINT @TableName + '.' + @ColumnName + ' (' + @DataType + ')'
    
            IF @ColumnName IS NOT NULL
            BEGIN
                IF @DataType IN ('int', 'bigint', 'tinyint', 'numeric', 'decimal')
                BEGIN
                    IF @SearchDecimal IS NOT NULL
                    BEGIN
                        SET @Query = 'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(CAST(' + @ColumnName + ' AS nvarchar(110)), 3630) ' +
                                     'FROM ' + @TableName + ' (NOLOCK) ' +
                                     ' WHERE ' + @ColumnName + ' = ' + CAST(@SearchDecimal AS nvarchar)
                        PRINT '    ' + @Query
                        INSERT INTO @Results
                        EXEC (@Query)
                    END
                END
                ELSE
                BEGIN
                    SET @Query = 'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) ' +
                                 'FROM ' + @TableName + ' (NOLOCK) ' +
                                 ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
                    PRINT '    ' + @Query
                    INSERT INTO @Results
                    EXEC (@Query)
                END
            END
        END 
    END
    
    SELECT ColumnName, ColumnValue FROM @Results
    END
    

提交回复
热议问题