Find a value anywhere in a database

前端 未结 18 883
小蘑菇
小蘑菇 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:02

    If you need to run such search only once then you can probably go with any of the scripts already shown in other answers. But otherwise, I’d recommend using ApexSQL Search for this. It’s a free SSMS addin and it really saved me a lot of time.

    Before running any of the scripts you should customize it based on the data type you want to search. If you know you are searching for datetime column then there is no need to search through nvarchar columns. This will speed up all of the queries above.

    0 讨论(0)
  • 2020-11-22 04:02

    Based on bnkdev's answer I modified Narayana's Code to search all columns even numeric ones.

    It'll run slower, but this version actually finds all matches not just those found in text columns.

    I can't thank this guy enough. Saved me days of searching by hand!

    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 QUOTENAME(COLUMN_NAME) > @ColumnName
            )
    
            IF @ColumnName IS NOT NULL
            BEGIN
                INSERT INTO #Results
                EXEC
                (
                    'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(CONVERT(varchar(max), ' + @ColumnName + '), 3630) 
                    FROM ' + @TableName + ' (NOLOCK) ' +
                    ' WHERE CONVERT(varchar(max), ' + @ColumnName + ') LIKE ' + @SearchStr2
                )
            END
        END 
    END
    
    SELECT ColumnName, ColumnValue FROM #Results
    END
    
    0 讨论(0)
  • 2020-11-22 04:02

    I have a solution from a while ago that I kept improving. Also searches within XML columns if told to do so, or searches integer values if providing a integer only string.

    /* Reto Egeter, fullparam.wordpress.com */
    
    DECLARE @SearchStrTableName nvarchar(255), @SearchStrColumnName nvarchar(255), @SearchStrColumnValue nvarchar(255), @SearchStrInXML bit, @FullRowResult bit, @FullRowResultRows int
    SET @SearchStrColumnValue = '%searchthis%' /* use LIKE syntax */
    SET @FullRowResult = 1
    SET @FullRowResultRows = 3
    SET @SearchStrTableName = NULL /* NULL for all tables, uses LIKE syntax */
    SET @SearchStrColumnName = NULL /* NULL for all columns, uses LIKE syntax */
    SET @SearchStrInXML = 0 /* Searching XML data may be slow */
    
    IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
    CREATE TABLE #Results (TableName nvarchar(128), ColumnName nvarchar(128), ColumnValue nvarchar(max),ColumnType nvarchar(20))
    
    SET NOCOUNT ON
    
    DECLARE @TableName nvarchar(256) = '',@ColumnName nvarchar(128),@ColumnType nvarchar(20), @QuotedSearchStrColumnValue nvarchar(110), @QuotedSearchStrColumnName nvarchar(110)
    SET @QuotedSearchStrColumnValue = QUOTENAME(@SearchStrColumnValue,'''')
    DECLARE @ColumnNameTable TABLE (COLUMN_NAME nvarchar(128),DATA_TYPE nvarchar(20))
    
    WHILE @TableName IS NOT NULL
    BEGIN
    SET @TableName =
    (
    SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = 'BASE TABLE'
    AND TABLE_NAME LIKE COALESCE(@SearchStrTableName,TABLE_NAME)
    AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
    AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0
    )
    IF @TableName IS NOT NULL
    BEGIN
    DECLARE @sql VARCHAR(MAX)
    SET @sql = 'SELECT 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 (' + CASE WHEN ISNUMERIC(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@SearchStrColumnValue,'%',''),'_',''),'[',''),']',''),'-','')) = 1 THEN '''tinyint'',''int'',''smallint'',''bigint'',''numeric'',''decimal'',''smallmoney'',''money'',' ELSE '' END + '''char'',''varchar'',''nchar'',''nvarchar'',''timestamp'',''uniqueidentifier''' + CASE @SearchStrInXML WHEN 1 THEN ',''xml''' ELSE '' END + ')
    AND COLUMN_NAME LIKE COALESCE(' + CASE WHEN @SearchStrColumnName IS NULL THEN 'NULL' ELSE '''' + @SearchStrColumnName + '''' END + ',COLUMN_NAME)'
    INSERT INTO @ColumnNameTable
    EXEC (@sql)
    WHILE EXISTS (SELECT TOP 1 COLUMN_NAME FROM @ColumnNameTable)
    BEGIN
    PRINT @ColumnName
    SELECT TOP 1 @ColumnName = COLUMN_NAME,@ColumnType = DATA_TYPE FROM @ColumnNameTable
    SET @sql = 'SELECT ''' + @TableName + ''',''' + @ColumnName + ''',' + CASE @ColumnType WHEN 'xml' THEN 'LEFT(CAST(' + @ColumnName + ' AS nvarchar(MAX)), 4096),'''
    WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ @ColumnName + '),'''
    ELSE 'LEFT(' + @ColumnName + ', 4096),''' END + @ColumnType + '''
    FROM ' + @TableName + ' (NOLOCK) ' +
    ' WHERE ' + CASE @ColumnType WHEN 'xml' THEN 'CAST(' + @ColumnName + ' AS nvarchar(MAX))'
    WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ @ColumnName + ')'
    ELSE @ColumnName END + ' LIKE ' + @QuotedSearchStrColumnValue
    INSERT INTO #Results
    EXEC(@sql)
    IF @@ROWCOUNT > 0 IF @FullRowResult = 1
    BEGIN
    SET @sql = 'SELECT TOP ' + CAST(@FullRowResultRows AS VARCHAR(3)) + ' ''' + @TableName + ''' AS [TableFound],''' + @ColumnName + ''' AS [ColumnFound],''FullRow>'' AS [FullRow>],*' +
    ' FROM ' + @TableName + ' (NOLOCK) ' +
    ' WHERE ' + CASE @ColumnType WHEN 'xml' THEN 'CAST(' + @ColumnName + ' AS nvarchar(MAX))'
    WHEN 'timestamp' THEN 'master.dbo.fn_varbintohexstr('+ @ColumnName + ')'
    ELSE @ColumnName END + ' LIKE ' + @QuotedSearchStrColumnValue
    EXEC(@sql)
    END
    DELETE FROM @ColumnNameTable WHERE COLUMN_NAME = @ColumnName
    END 
    END
    END
    SET NOCOUNT OFF
    
    SELECT TableName, ColumnName, ColumnValue, ColumnType, COUNT(*) AS Count FROM #Results
    GROUP BY TableName, ColumnName, ColumnValue, ColumnType
    

    Source: http://fullparam.wordpress.com/2012/09/07/fck-it-i-am-going-to-search-all-tables-all-collumns/

    0 讨论(0)
  • 2020-11-22 04:03

    If you have phpMyAdmin installed use its Search feature.

    Select your DataBase.

    Be sure you do have selected DataBase, not a table, otherwise you'll get a completely different search dialog.

    1. Click Search tab
    2. List item Choose the search term you want
    3. Choose the tables to search
    0 讨论(0)
  • 2020-11-22 04:03

    For Development purpose you can just export the required tables data into a single HTML and make a direct search on it.

    0 讨论(0)
  • 2020-11-22 04:07
    -- exec pSearchAllTables 'M54*'
    
    ALTER PROC pSearchAllTables (@SearchStr NVARCHAR(100))
    AS
    BEGIN
        -- A procedure to search all tables in a database for a value
        -- Note: Use * or % for wildcard
    
        DECLARE 
            @Results TABLE([Schema.Table.ColumnName] NVARCHAR(370), ColumnValue NVARCHAR(3630))
    
        SET NOCOUNT ON
    
        DECLARE 
            @TableName NVARCHAR(256) = ''
            , @ColumnName NVARCHAR(128)     
            , @SearchStr2 NVARCHAR(110) = QUOTENAME(REPLACE(@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 
            [Schema.Table.ColumnName]
            , ColumnValue 
        FROM @Results
        GROUP BY 
            [Schema.Table.ColumnName]
            , ColumnValue 
    
    END
    
    0 讨论(0)
提交回复
热议问题