在表的所有列中搜索值?

时间:2011-06-30 19:11:30

标签: sql sql-server

我已经找到了答案,但我找到的只是人们询问如何搜索数据库中所有表的所有列的值。我只想搜索特定表的所有列。人们为所有表格提出的代码问题很复杂,我很难弄清楚它在哪里搜索特定的表格。有人可以帮帮我吗?感谢

9 个答案:

答案 0 :(得分:4)

只需使用某些第三方工具即可。有几个是100%免费的,你不能错过任何这些,因为它们将为你节省大量的时间。

ApexSQL Search(搜索架构和数据),SSMS Toolpack(搜索架构和数据但不是免费的SQL Server 2012),SQL Search(仅搜索数据)。

坦率地说,我真的不明白为什么即使非常有经验的DBA也会为此编写脚本,如果他们可以免费使用某些工具来完成这项工作。

答案 1 :(得分:2)

我不知道您要搜索的列类型或数据值,但我猜您正在尝试在多个文本列中搜索子字符串。

这是Full-Text Search的工作。

不要在LIKE '%' + @SearchStr + '%'上浪费时间。您必须编写许多复杂的代码来支持它,并且该解决方案无论如何都不会很好。

答案 2 :(得分:2)

在我提到的similar question SQL Workbench / J中。

搜索数据库的命令也可以仅限于一个表。所以即使这个问题特定于PostgreSQL,该工具也适用于SQL Server以及我所知道的。

答案 3 :(得分:1)

我修改了这个存储过程,将表名作为第二个参数,只搜索该表中的数据:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SearchOneTable]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[SearchOneTable]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROC [dbo].[SearchOneTable]
(
    @SearchStr nvarchar(100) = 'A',
    @TableName nvarchar(256) = 'dbo.Alerts'
)
AS
BEGIN

    CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))

    --SET NOCOUNT ON

    DECLARE @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
    SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
    --SET @SearchStr2 = QUOTENAME(@SearchStr, '''') --exact match
    SET @ColumnName = ' '


        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 
    SELECT ColumnName, ColumnValue FROM #Results
END


GO

答案 4 :(得分:1)

这是一个解决方案,就像@ Decker97的方法一样,从元数据中找出哪些列符合文本搜索条件。假设2005+使用XML PATH以及sys.columns,sys.tables等。支持TEXT / NTEXT / CHAR / NCHAR / VARCHAR / NVARCHAR,甚至在适当的搜索字符串上放置前导N.不支持XML列。它的功能略有不同,它为每个表返回一个结果集,而不是为每一个列返回一个结果集,因此即使多个列匹配,每个实际表行也只能得到一行。如果目标是了解它是如何工作而不是简单地有一个解决方案,它可能需要更多的东西...也许我应该博客这个问题(我可能不应该懒惰,实际上建立列列表而不是只使用SELECT *)。

DECLARE @SearchTerm NVARCHAR(32) = 'foo';

DECLARE @TableName NVARCHAR(128) = NULL;

SET NOCOUNT ON;

DECLARE @s NVARCHAR(MAX) = '';

WITH [tables] AS
(
    SELECT [object_id] 
        FROM sys.tables AS t
        WHERE (name = @TableName OR @TableName IS NULL)
        AND EXISTS
        (
            SELECT 1 
                FROM sys.columns
                WHERE [object_id] = t.[object_id]
                AND system_type_id IN (35,99,167,175,231,239)
        )
)
SELECT @s = @s + 'SELECT ''' 
    + REPLACE(QUOTENAME(OBJECT_SCHEMA_NAME([object_id])),'''','''''')
    + '.' + REPLACE(QUOTENAME(OBJECT_NAME([object_id])), '''','''''')
    + ''',* FROM ' + QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
    + '.' + QUOTENAME(OBJECT_NAME([object_id])) + ' WHERE ' + 
    (
        SELECT QUOTENAME(name) + ' LIKE ' + CASE 
            WHEN system_type_id IN (99,231,239) 
            THEN 'N' ELSE '' END
            + '''%' + @SearchTerm + '%'' OR '
        FROM sys.columns
        WHERE [object_id] = [tables].[object_id]
        AND system_type_id IN (35,99,167,175,231,239)
        ORDER BY name
        FOR XML PATH(''), TYPE
).value('.[1]', 'nvarchar(max)') + CHAR(13) + CHAR(10)
FROM [tables];

SELECT @s = REPLACE(@s,' OR ' + CHAR(13),';' + CHAR(13));

/*
    make sure you use Results to Text and adjust Tools / Options / 
    Query Results / SQL Server / Results to Text / Maximum number
    of characters if you want a chance at trusting this output 
    (the number of tables/columns will certainly have the ability
    to exceed the output limitation)
*/

SELECT @s;
-- EXEC sp_executeSQL @s;

答案 5 :(得分:0)

这听起来只是想知道哪些表和列存储了一些数据,而不是您想知道在执行代码期间或更改它。我也有这个问题,这解决了它:

以SQL格式下载您的数据库(例如,使用phpmyadmin),使用文本编辑器打开它并搜索您想要的事件。

答案 6 :(得分:0)

Cutesie小小的解决方法涉及更多的输入或Excel剪切/格式化:

WHERE子句中的VALUE IN <fields>运算符反转为FIELD IN <values>(与SELECT col_1, col_2, ... , col_n FROM <table> WHERE CAST(<value> AS varchar(max)) IN ( CAST(col_1 AS varchar(max)), CAST(col_2 AS varchar(max)), ..., CAST(col_n AS varchar(max)) ) 的更常见用例相反)。

ISNULL

由于varchar是一种非常具有可塑性的数据类型,因此这变得非常简单(您可以根据需要抛出NULLIF / Handler进行修改),并且根据用例的不同,可能会使用多个一个搜索值。

答案 7 :(得分:0)

我遇到过这个问题,通常是在从CSV文件中上传数据后,我必须修改逗号&#39;,&#39;在文本字段中,以便数据正确加载&amp;一旦在SQL Server中,需要将修改后的角色更改回逗号&amp;能够搜索整个表格很有帮助。 mssqltips的Greg Robidoux发布了一个执行此操作的存储过程,在指定表的列中搜索特定的String值。您可以找到它与SPROC一起使用不使用光标&amp;更多详情:

https://www.mssqltips.com/sqlservertip/1522/searching-and-finding-a-string-value-in-all-columns-in-a-sql-server-table/

我在下面发布了原始的SPROC:

USE master 
GO 

CREATE PROCEDURE dbo.sp_FindStringInTable @stringToFind VARCHAR(100), @schema sysname, @table sysname 
AS 

DECLARE @sqlCommand VARCHAR(8000) 
DECLARE @where VARCHAR(8000) 
DECLARE @columnName sysname 
DECLARE @cursor VARCHAR(8000) 

BEGIN TRY 
   SET @sqlCommand = 'SELECT * FROM [' + @schema + '].[' + @table + '] WHERE' 
   SET @where = '' 

   SET @cursor = 'DECLARE col_cursor CURSOR FOR SELECT COLUMN_NAME 
   FROM ' + DB_NAME() + '.INFORMATION_SCHEMA.COLUMNS 
   WHERE TABLE_SCHEMA = ''' + @schema + ''' 
   AND TABLE_NAME = ''' + @table + ''' 
   AND DATA_TYPE IN (''char'',''nchar'',''ntext'',''nvarchar'',''text'',''varchar'')' 

   EXEC (@cursor) 

   OPEN col_cursor    
   FETCH NEXT FROM col_cursor INTO @columnName    

   WHILE @@FETCH_STATUS = 0    
   BEGIN    
       IF @where <> '' 
           SET @where = @where + ' OR' 

       SET @where = @where + ' [' + @columnName + '] LIKE ''' + @stringToFind + '''' 
       FETCH NEXT FROM col_cursor INTO @columnName    
   END    

   CLOSE col_cursor    
   DEALLOCATE col_cursor  

   SET @sqlCommand = @sqlCommand + @where 
   PRINT @sqlCommand 
   EXEC (@sqlCommand)  
END TRY 
BEGIN CATCH 
   PRINT 'There was an error. Check to make sure object exists.'
   PRINT error_message()

   IF CURSOR_STATUS('variable', 'col_cursor') <> -3 
   BEGIN 
       CLOSE col_cursor    
       DEALLOCATE col_cursor  
   END 
END CATCH 

答案 8 :(得分:0)

我发现最好的答案只是来自表格select *,然后复制&amp;粘贴到Excel并按Ctrl + F