【问题标题】:Search for one value in any column of any table inside a database在数据库内任何表的任何列中搜索一个值
【发布时间】:2010-10-17 02:02:00
【问题描述】:

有没有一种方法可以在一个 MS SQL Server 数据库内的任何表的任何列中搜索一个值(在我的情况下,它是 char(64) 类型的 UID)?

我坐在一个巨大的数据库前,不知道如何将这些表链接在一起。要找出这一点,我想列出所有表以及任何行中包含特定值的列。这可能吗?

一种方法可能是将整个数据库转储到一个文本文件中,然后使用任何文本编辑器搜索该值 - 但如果数据库太大,这将是纯粹的痛苦。

【问题讨论】:

标签: tsql


【解决方案1】:

如何搜索所有的所有列 关键字的数据库中的表?

http://vyaskn.tripod.com/search_all_columns_in_all_tables.htm

编辑:这是实际的 T-SQL,以防链接失效:

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

【讨论】:

  • 搜索uniqueidentifier时不起作用(传入'')
  • 别忘了把临时表放在最后!
【解决方案2】:

下面提到的所有第三方工具都是 100% 免费的。

我使用ApexSQL Search 在表格中搜索对象和数据时取得了很好的成功。它还具有其他几个功能,例如关系图等……

我在大型(40GB TFS 数据库)数据库上有点慢……

除此之外,还有SSMS Tools pack 提供了许多非常有用的其他功能,即使这些功能与搜索文本没有直接关系。

【讨论】:

    【解决方案3】:

    我扩展了代码,因为它没有告诉我'record number',我必须重新找到它。

    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
    
    -- Copyright @ 2012 Gyula Kulifai. All rights reserved.
    -- Extended By: Gyula Kulifai
    -- Purpose: To put key values, to exactly determine the position of search
    -- Resources: Anatoly Lubarsky
    -- Date extension: 19th October 2012 12:24 GMT
    -- Tested on: SQL Server 10.0.5500 (SQL Server 2008 SP3)
    
    CREATE TABLE #Results (TableName nvarchar(370), KeyValues nvarchar(3630), ColumnName nvarchar(370), ColumnValue nvarchar(3630))
    
    SET NOCOUNT ON
    
    DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
        ,@TableShortName nvarchar(256)
        ,@TableKeys nvarchar(512)
        ,@SQL nvarchar(3830)
    
    SET  @TableName = ''
    SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
    
    WHILE @TableName IS NOT NULL
    BEGIN
        SET @ColumnName = ''
    
        -- Scan Tables
        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
        )
        Set @TableShortName=PARSENAME(@TableName, 1)
        -- print @TableName + ';' + @TableShortName +'!' -- *** DEBUG LINE ***
    
            -- LOOK Key Fields, Set Key Columns
            SET @TableKeys=''
            SELECT @TableKeys = @TableKeys + '''' + QUOTENAME([name]) + ': '' + CONVERT(nvarchar(250),' + [name] + ') + ''' + ',' + ''' + '
             FROM syscolumns 
             WHERE [id] IN (
                SELECT [id] 
                 FROM sysobjects 
                 WHERE [name] = @TableShortName)
               AND colid IN (
                SELECT SIK.colid 
                 FROM sysindexkeys SIK 
                 JOIN sysobjects SO ON 
                    SIK.[id] = SO.[id]  
                 WHERE 
                    SIK.indid = 1
                    AND SO.[name] = @TableShortName)
            If @TableKeys<>''
                SET @TableKeys=SUBSTRING(@TableKeys,1,Len(@TableKeys)-8)
            -- Print @TableName + ';' + @TableKeys + '!' -- *** DEBUG LINE ***
    
        -- Search in Columns
        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
            ) -- Set ColumnName
    
            IF @ColumnName IS NOT NULL
            BEGIN
                SET @SQL='
                    SELECT 
                        ''' + @TableName + '''
                        ,'+@TableKeys+'
                        ,''' + @ColumnName + '''
                    ,LEFT(' + @ColumnName + ', 3630) 
                    FROM ' + @TableName + ' (NOLOCK) ' +
                    ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
                --Print @SQL -- *** DEBUG LINE ***
                INSERT INTO #Results
                    Exec (@SQL)
            END -- IF ColumnName
        END -- While Table and Column
    END --While Table
    
    SELECT TableName, KeyValues, ColumnName, ColumnValue FROM #Results
    END
    

    【讨论】:

      【解决方案4】:

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

      我有一个不久前的解决方案,我一直在改进。如果被告知,还会在 XML 列中搜索,或者如果提供仅整数字符串,则搜索整数值。

      /* 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
      

      【讨论】:

        【解决方案5】:

        我在 https://gallery.technet.microsoft.com/scriptcenter/c0c57332-8624-48c0-b4c3-5b31fe641c58 找到了一个相当强大的解决方案,我认为值得指出。它搜索以下类型的列:varchar、char、nvarchar、nchar、text。它工作得很好,并且支持特定的表格搜索以及多个搜索词。

        【讨论】:

          【解决方案6】:

          有一个不错的脚本可用 http://www.reddyss.com/SQLDownloads.aspx

          为了能够在任何数据库上使用它,您可以像这样创建它: http://nickstips.wordpress.com/2010/10/18/sql-making-a-stored-procedure-available-to-all-databases/

          不知道有没有其他办法。

          要使用它,请使用以下内容:

          use name_of_database
          
          EXEC spUtil_SearchText 'value_searched', 0, 0
          

          【讨论】:

            【解决方案7】:

            在尝试@regeter's solution 并在我搜索外键/主键以查看它存在的所有表/列时看到它并没有解决我的问题后,它不起作用。在阅读了另一个尝试使用唯一标识符的人如何失败后,我进行了修改,这是更新后的结果:(适用于 int 和 guid...您将看到如何轻松扩展)

            CREATE PROC [dbo].[SearchAllTables_Like]
            (
                    @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 ('guid', 'int', '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
            

            【讨论】:

              猜你喜欢
              • 2018-05-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-01-09
              • 2021-12-12
              • 2019-08-26
              • 2021-02-25
              相关资源
              最近更新 更多