【问题标题】:Find a value anywhere in a database在数据库中的任何位置查找值
【发布时间】:2010-09-30 23:36:38
【问题描述】:

给定一个数字,我如何发现它可以在哪个表和列中找到?

我不在乎它是否快,它只需要工作。

【问题讨论】:

  • 您想在所有列/行中搜索特定数字吗?您可以将其限制为数字列吗?整数列?身份列?
  • 所有列都是最好的,但数字会做。标识列过于具体
  • 您可能必须编写一个简短的脚本来从数据库中查询元数据(在本例中为表/列的列表),并发出一系列查找值的选择语句。
  • 这很古老,但为什么不直接转储并 grep 转储呢?
  • phpmyadmin 允许这个非常简单

标签: sql-server tsql


【解决方案1】:

This might help you。 - 来自纳拉亚纳维亚斯。它搜索给定数据库中所有表的所有列。我以前用过,效果很好。

这是来自上述链接的存储过程 - 我所做的唯一更改是将临时表替换为表变量,这样您就不必每次都记住删除它。

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

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

        IF @ColumnName IS NOT NULL
        BEGIN
            INSERT INTO @Results
            EXEC
            (
                'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
                FROM ' + @TableName + 
                ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
            )
        END
    END 
END

SELECT ColumnName, ColumnValue FROM @Results
END

执行存储过程:

 EXEC SearchAllTables 'YourStringHere'

【讨论】:

  • 仅供参考,此脚本仅搜索文本字段,而不搜索数字字段。就我而言,它起作用了,因为开发人员将数字存储在 varchar 中,但通常无法找到数字。
  • 我们可以使用单个查询而不是使用存储过程来做到这一点吗?
  • 这里唯一的缺点是,如果同时检查每个表的所有列(以避免在同一数据页上多次读取),效率会更高。同样,我认为在上面的脚本上进行这种优化会很容易(前段时间我已经做过类似的事情)。
  • 如果我们希望列包含两个搜索字符串怎么办?我的意思是在不同行中包含两个字符串的所有列。
【解决方案2】:

如果您只需要运行一次此类搜索,那么您可能可以使用其他答案中已经显示的任何脚本。但除此之外,我建议为此使用ApexSQL Search。这是一个免费的 SSMS 插件,真的为我节省了很多时间。

在运行任何脚本之前,您应该根据要搜索的数据类型对其进行自定义。如果您知道要搜索 datetime 列,则无需搜索 nvarchar 列。这将加快上述所有查询的速度。

【讨论】:

  • 花了我一段时间才弄清楚在哪里执行此操作,任何阅读此评论的人都可以通过从接受的答案中更改此部分来在查询中完成:AND DATA_TYPE IN ('char', 'varchar ', 'nchar', 'nvarchar')
  • ApexSQL 搜索是一款出色的工具。我认为这应该是最佳答案,因为工具是一个抽象概念,不涉及弄乱脏脚本。
  • 另外请注意,虽然 ApexSQL 让您为他们的一些工具付费,但这个工具是免费的。你只需要给他们你的电子邮件。一个很棒的工具,在挖掘未记录的 3rd 方数据库时,这对我有很大帮助:)
  • 这应该是最佳答案,恕我直言。过滤不同数据类型的能力很棒。我对此的唯一抱怨是,用于选择/取消选择“要搜索的表”的 GUI 是一个复选框列表,带有 NO 选中/取消选中所有选项或多选-和切换能力。因此,如果您想取消选中所有系统对象(默认情况下*已选中*,这很愚蠢),您必须通过 space-arrowdown-space-arrowdown *ad-nauseum* 练习.但值得庆幸的是,它足够高效,您不必这样做。让它搜索并做它的事!
  • ApexSQL Search 绝对是最好的解决方案。我刚刚尝试使用脚本在数据库中查找电子邮件地址 - 8:30 分钟后,我放弃了。安装 ApexSQL Search 后,我搜索了完全相同的字符串,它在 11 个表中找到了 31 次。我没有准确计时,但花了不到一分钟
【解决方案3】:

根据 bnkdev 的回答,我修改了 Narayana's 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 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

【讨论】:

  • 已编辑以解决“结果空间不足,无法将 uniqueidentifier 值转换为 char”错误。这现在也适用于 XML 列。
  • 这是一个新的:不允许从数据类型 image 到 varchar(max) 的显式转换。我将尝试自己解决此问题,但如果有人击败我,请告诉我,谢谢!
  • 好的,我刚刚从 kd7 的代码中添加了一段,只搜索我正在寻找的数据类型,这些数据类型会将这些图像列排除在我的搜索之外,导致错误消失......并且 DATA_TYPE 不是IN('图像')
  • 在 SQL Server 2014 中获取“将一个或多个字符从 XML 转换为目标排序规则不可能的错误”。
  • 您可以为不同的变量类型提供不同的版本。这样你就不会投射,它会运行得更快。您还可以将文件类型与搜索可转换类型进行比较。整数可以在 varchar 字段中。
【解决方案4】:

这是我对这个问题的独立看法,用于我自己的工作。它适用于 SQL2000 及更高版本,允许使用通配符、列过滤,并且将搜索大多数普通数据类型。

伪代码描述可以是select * from * where any like 'foo'

--------------------------------------------------------------------------------
-- Search all columns in all tables in a database for a string.
-- Does not search: image, sql_variant or user-defined types.
-- Exact search always for money and smallmoney; no wildcards for matching these.
--------------------------------------------------------------------------------
declare @SearchTerm nvarchar(4000) -- Can be max for SQL2005+
declare @ColumnName sysname

--------------------------------------------------------------------------------
-- SET THESE!
--------------------------------------------------------------------------------
set @SearchTerm = N'foo' -- Term to be searched for, wildcards okay
set @ColumnName = N'' -- Use to restrict the search to certain columns, wildcards okay, null or empty string for all cols
--------------------------------------------------------------------------------
-- END SET
--------------------------------------------------------------------------------

set nocount on

declare @TabCols table (
      id int not null primary key identity
    , table_schema sysname not null
    , table_name sysname not null
    , column_name sysname not null
    , data_type sysname not null
)
insert into @TabCols (table_schema, table_name, column_name, data_type)
    select t.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE
    from INFORMATION_SCHEMA.TABLES t
        join INFORMATION_SCHEMA.COLUMNS c on t.TABLE_SCHEMA = c.TABLE_SCHEMA
            and t.TABLE_NAME = c.TABLE_NAME
    where 1 = 1
        and t.TABLE_TYPE = 'base table'
        and c.DATA_TYPE not in ('image', 'sql_variant')
        and c.COLUMN_NAME like case when len(@ColumnName) > 0 then @ColumnName else '%' end
    order by c.TABLE_NAME, c.ORDINAL_POSITION

declare
      @table_schema sysname
    , @table_name sysname
    , @column_name sysname
    , @data_type sysname
    , @exists nvarchar(4000) -- Can be max for SQL2005+
    , @sql nvarchar(4000) -- Can be max for SQL2005+
    , @where nvarchar(4000) -- Can be max for SQL2005+
    , @run nvarchar(4000) -- Can be max for SQL2005+

while exists (select null from @TabCols) begin

    select top 1
          @table_schema = table_schema
        , @table_name = table_name
        , @exists = 'select null from [' + table_schema + '].[' + table_name + '] where 1 = 0'
        , @sql = 'select ''' + '[' + table_schema + '].[' + table_name + ']' + ''' as TABLE_NAME, * from [' + table_schema + '].[' + table_name + '] where 1 = 0'
        , @where = ''
    from @TabCols
    order by id

    while exists (select null from @TabCols where table_schema = @table_schema and table_name = @table_name) begin

        select top 1
              @column_name = column_name
            , @data_type = data_type
        from @TabCols
        where table_schema = @table_schema
            and table_name = @table_name
        order by id

        -- Special case for money
        if @data_type in ('money', 'smallmoney') begin
            if isnumeric(@SearchTerm) = 1 begin
                set @where = @where + ' or [' + @column_name + '] = cast(''' + @SearchTerm + ''' as ' + @data_type + ')' -- could also cast the column as varchar for wildcards
            end
        end
        -- Special case for xml
        else if @data_type = 'xml' begin
            set @where = @where + ' or cast([' + @column_name + '] as nvarchar(max)) like ''' + @SearchTerm + ''''
        end
        -- Special case for date
        else if @data_type in ('date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time') begin
            set @where = @where + ' or convert(nvarchar(50), [' + @column_name + '], 121) like ''' + @SearchTerm + ''''
        end
        -- Search all other types
        else begin
            set @where = @where + ' or [' + @column_name + '] like ''' + @SearchTerm + ''''
        end

        delete from @TabCols where table_schema = @table_schema and table_name = @table_name and column_name = @column_name

    end

    set @run = 'if exists(' + @exists + @where + ') begin ' + @sql + @where + ' print ''' + @table_name + ''' end'
    print @run
    exec sp_executesql @run

end

set nocount off

我不把它放在 proc 形式中,因为我不想在数百个数据库中维护它,而且它确实是用于临时工作的。请随时对错误修复发表评论。

【讨论】:

  • 谢谢,但我在 phpMyAdmin 中得到的只是语法错误。自编写以来,SQL 是否发生了一些变化?
  • @NoBugs 这是用 T-SQL 为 SQL Server 编写的。
  • @NoBugs:您需要将代码封装在您自己的存储过程或其他一些函数中。
  • 只是为了澄清输出,如果从 Microsoft SQL Server Management Studio 运行它,只有在找到搜索词时才会弹出“结果”选项卡。如果未找到搜索词,则只会打开带有已执行搜索语句的“消息”选项卡。 “消息”选项卡不包含任何结果,但在找到搜索词时也会与“结果”选项卡一起打开。
  • 这太棒了!使用购买的应用程序,我不想将自定义数据库对象保存到他们的架构中。谢谢!
【解决方案5】:

我优化了 Alllain Lalonde 的答案 (https://stackoverflow.com/a/436676/412368)。 仍然支持数值。应该快大约 4-5 倍(1:03 对 4:30),在具有 7GB 数据库的桌面上进行测试。 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

【讨论】:

    【解决方案6】:

    我有一个不久前的解决方案,我一直在改进。如果被告知,还会在 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
    

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

    【讨论】:

    • 这是唯一适用于我的权限的答案,不仅搜索了字符串,而且没有被我的表格破坏。
    • 这是唯一对我有用的。其余的给了我一个算术溢出错误,将 nvarchar 转换为数字数据类型。我怀疑是从 Oracle 带入 SQL Server 的大 id 数字进入结果。没有尝试诊断
    【解决方案7】:

    这是我解决这个问题的方法。在 SQLServer2008R2 上测试

    CREATE PROC SearchAllTables
    @SearchStr nvarchar(100)
    AS
    BEGIN
    DECLARE @dml nvarchar(max) = N''        
    IF OBJECT_ID('tempdb.dbo.#Results') IS NOT NULL DROP TABLE dbo.#Results
    CREATE TABLE dbo.#Results
     ([tablename] nvarchar(100), 
      [ColumnName] nvarchar(100), 
      [Value] nvarchar(max))  
    SELECT @dml += ' SELECT ''' + s.name + '.' + t.name + ''' AS [tablename], ''' + 
                    c.name + ''' AS [ColumnName], CAST(' + QUOTENAME(c.name) + 
                   ' AS nvarchar(max)) AS [Value] FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) +
                   ' (NOLOCK) WHERE CAST(' + QUOTENAME(c.name) + ' AS nvarchar(max)) LIKE ' + '''%' + @SearchStr + '%'''
    FROM sys.schemas s JOIN sys.tables t ON s.schema_id = t.schema_id
                       JOIN sys.columns c ON t.object_id = c.object_id
                       JOIN sys.types ty ON c.system_type_id = ty.system_type_id AND c .user_type_id = ty .user_type_id
    WHERE t.is_ms_shipped = 0 AND ty.name NOT IN ('timestamp', 'image', 'sql_variant')
    
    INSERT dbo.#Results
    EXEC sp_executesql @dml
    
    SELECT *
    FROM dbo.#Results
    END
    

    【讨论】:

      【解决方案8】:

      感谢真正有用的脚本。

      如果您的表有不可转换的字段,您可能需要在代码中添加以下修改:

      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 NOT IN ('text', 'image', 'ntext')                 
                  AND QUOTENAME(COLUMN_NAME) > @ColumnName
          )
      

      克里斯

      【讨论】:

        【解决方案9】:

        在这里,非常甜蜜的小解决方案:

        1) create a store procedure:
        
        create procedure get_table
        @find_str varchar(50)
        as 
        begin
          declare @col_name varchar(500), @tab_name varchar(500);
          declare @find_tab TABLE(table_name varchar(100), column_name varchar(100));
        
          DECLARE tab_col cursor for 
          select C.name as 'col_name', T.name as tab_name
          from sys.tables as T
          left outer join sys.columns as C on  C.object_id=T.object_id
          left outer join sys.types as TP on  C.system_type_id=TP.system_type_id
          where type='U' 
          and TP.name in('text','ntext','varchar','char','nvarchar','nchar');
        
          open tab_col
          fetch next from tab_col into @col_name, @tab_name
        
          while @@FETCH_STATUS = 0
          begin        
            insert into @find_tab 
            exec('select ''' +  @tab_name + ''',''' + @col_name + ''' from ' + @tab_name + 
            ' where ' + @col_name + '=''' + @find_str + ''' group by ' + 
            @col_name + ' having count(*)>0');
        
            fetch next from tab_col into @col_name, @tab_name;
          end
          CLOSE tab_col;  
          DEALLOCATE tab_col; 
          select table_name, column_name from @find_tab;
        
        end
        

        ===========================

        2) call procedure by calling store procedure:
        exec get_table 'serach_string';
        

        【讨论】:

          【解决方案10】:

          我曾经为自己写过一个工具来做那件事:

          a7 SqlTools

          它是免费和开源的:

          github link

          【讨论】:

            【解决方案11】:

            使用 JOIN 和 CURSOR 的另一种方式:

            USE My_Database;
            
            -- Store results in a local temp table so that.  I'm using a
            -- local temp table so that I can access it in SP_EXECUTESQL.
            create table #tmp (
                tbl nvarchar(max),
                col nvarchar(max),
                val nvarchar(max)   
            );
            
            declare @tbl nvarchar(max);
            declare @col nvarchar(max);
            declare @q nvarchar(max);
            declare @search nvarchar(max) = 'my search key';
            
            -- Create a cursor on all columns in the database
            declare c cursor for
            SELECT tbls.TABLE_NAME, cols.COLUMN_NAME  FROM INFORMATION_SCHEMA.TABLES AS tbls
            JOIN INFORMATION_SCHEMA.COLUMNS AS cols
            ON tbls.TABLE_NAME = cols.TABLE_NAME
            
            -- For each table and column pair, see if the search value exists.
            open c
            fetch next from c into @tbl, @col
            while @@FETCH_STATUS = 0
            begin
                -- Look for the search key in current table column and if found add it to the results.
                SET @q = 'INSERT INTO #tmp SELECT ''' + @tbl + ''', ''' + @col + ''', ' + @col + ' FROM ' + @tbl + ' WHERE ' + @col + ' LIKE ''%' + @search + '%'''
                EXEC SP_EXECUTESQL @q
                fetch next from c into @tbl, @col
            end
            close c
            deallocate c
            
            -- Get results
            select * from #tmp
            
            -- Remove local temp table.
            drop table #tmp
            

            【讨论】:

              【解决方案12】:

              如果您安装了 phpMyAdmin,请使用其 搜索 功能。

              选择您的数据库。

              确保您确实选择了数据库,而不是表,否则您将获得完全不同的搜索对话框。

              1. 点击搜索标签
              2. 列表项选择你想要的搜索词
              3. 选择要搜索的表

              【讨论】:

              • 5 小时寻找这个答案,谢谢。
              【解决方案13】:

              您可能需要为您的数据库构建一个inverted index。速度肯定很快。

              【讨论】:

                【解决方案14】:
                -- 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
                

                【讨论】:

                • 我不清楚这是如何工作的。看起来有 2 个搜索字符串,还是一个搜索和替换字符串?如果我只想搜索,我在哪里放置我正在寻找的字符串?
                【解决方案15】:

                出于开发目的,您只需将所需的表格数据导出到单个 HTML 中并直接搜索即可。

                【讨论】:

                  【解决方案16】:

                  假设如果要获取数据库MyDatabase中所有名称为列名包含logintime的表,下面是代码示例

                      use MyDatabase
                  
                      SELECT t.name AS table_name,
                      SCHEMA_NAME(schema_id) AS schema_name,
                      c.name AS column_name
                      FROM sys.tables AS t
                      INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
                      WHERE c.name LIKE '%logintime%'
                      ORDER BY schema_name, table_name;
                  

                  【讨论】:

                    【解决方案17】:

                    数据库客户端工具(如DBeaverphpMyAdmin)通常支持对整个数据库进行全文搜索。

                    【讨论】:

                      【解决方案18】:

                      我正在寻找一个数字值 = 6.84 - 使用此处的其他答案,我能够将搜索限制在此

                      Declare @sourceTable Table(id INT NOT NULL IDENTITY PRIMARY KEY, table_name varchar(1000), column_name varchar(1000))
                      Declare @resultsTable Table(id INT NOT NULL IDENTITY PRIMARY KEY, table_name varchar(1000))
                      
                      Insert into @sourceTable(table_name, column_name)
                      select schema_name(t.schema_id) + '.' + t.name as[table], c.name as column_name
                      from sys.columns c
                      join sys.tables t
                      on t.object_id = c.object_id
                      where type_name(user_type_id) in ('decimal', 'numeric', 'smallmoney', 'money', 'float', 'real')
                      order by[table], c.column_id;
                      
                      DECLARE db_cursor CURSOR FOR
                      Select table_name, column_name from @sourceTable
                      DECLARE @mytablename VARCHAR(1000);
                      DECLARE @mycolumnname VARCHAR(1000);
                      
                      OPEN db_cursor;
                      FETCH NEXT FROM db_cursor INTO @mytablename, @mycolumnname
                      
                      WHILE @ @FETCH_STATUS = 0
                      BEGIN
                          Insert into @ResultsTable(table_name)
                          EXEC('SELECT ''' + @mytablename + '.' + @mycolumnname + '''  FROM ' + @mytablename + ' (NOLOCK) ' +
                          ' WHERE ' + @mycolumnname + '=6.84')
                          FETCH NEXT FROM db_cursor INTO @mytablename, @mycolumnname  
                      END;
                      CLOSE db_cursor;
                      DEALLOCATE db_cursor;
                      Select Distinct(table_name) from @ResultsTable
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2017-07-12
                        • 2019-01-29
                        • 2018-04-04
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-12-11
                        相关资源
                        最近更新 更多