데이터베이스의 어느 곳에서나 값 찾기


253

주어진 #, 주어진 테이블과 열에서 어떻게 찾을 수 있습니까?

나는 그것이 빠르면 신경 쓰지 않고 작동해야합니다.


1
특정 번호의 모든 열 / 행을 검색 하시겠습니까? 숫자 열로 제한 할 수 있습니까? 정수 열? 신원 열?
Michael Haren

1
모든 열이 가장 좋지만 숫자로 표시됩니다. 들여 쓰기 열이 너무 구체적입니다
Allain Lalonde

1
데이터베이스에서 메타 데이터 (이 경우 테이블 / 열 목록)를 쿼리하기 위해 간단한 스크립트를 작성하고 값을 찾는 일련의 select 문을 실행해야합니다.
Draemon

9
이것은 고대이지만 왜 덤프를하고 덤프를 grep하지 않습니까?
baordog

3
phpmyadmin은 이것을 아주 간단하게 허용합니다
Matoeil

답변:


284

도움이 될 수 있습니다 . -Narayana Vyas에서. 주어진 데이터베이스에서 모든 테이블의 모든 열을 검색합니다. 나는 그것을 전에 사용했고 작동합니다.

이것은 위의 링크에서 저장 된 Proc입니다. 내가 한 유일한 변경 사항은 테이블 변수에 임시 테이블을 대체하는 것이므로 매번 삭제해야한다는 것을 기억할 필요가 없습니다.

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 + ' (NOLOCK) ' +
                ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
            )
        END
    END 
END

SELECT ColumnName, ColumnValue FROM @Results
END

17
참고로이 스크립트는 숫자 필드가 아닌 텍스트 필드 만 검색합니다. 필자의 경우 개발자가 varchar에 숫자를 저장했지만 일반적으로 숫자를 찾는 것이 효과가 없기 때문에 효과가있었습니다.
Allain Lalonde

1
저장 프로 시저 대신 단일 쿼리를 사용하여이 작업을 수행 할 수 있습니까?
Freakyuser

6
어떻게 간단한 SQL 프로 시저에 저작권을 부여 할 수 있습니까? 그것은 나를 당황
데이비드 안드레이 네드에게

3
@DavidAndreiNed, 그는 적어도 그가 한 방식으로는 할 수 없습니다. 이것이 2009 년의 사례인지는 확실하지 않지만 요즘은 CC-BY-SA 3.0입니다.
Arturo Torres Sánchez

2
스크립트에서 찾을 문자열을 어디에 배치해야합니까? @ SearchStr2 세트?
랜디 퀘커

77

이러한 검색을 한 번만 실행 해야하는 경우 이미 다른 답변에 표시된 스크립트를 사용할 수 있습니다. 그러나 그렇지 않으면 ApexSQL 검색 을 사용하는 것이 좋습니다 . 그것은 무료 SSMS addin이며 실제로 많은 시간을 절약했습니다.

스크립트를 실행하기 전에 검색하려는 데이터 유형에 따라 스크립트를 사용자 정의해야합니다. datetime 열을 검색한다는 것을 알고 있으면 nvarchar 열을 통해 검색 할 필요가 없습니다. 위의 모든 쿼리 속도가 빨라집니다.


1
이 작업을 수행 할 위치를 파악하는 데 시간이 걸렸습니다.이 의견을 읽는 사람은이 답변을 허용 된 답변에서 변경하여 쿼리에서 수행 할 수 있습니다 .AND DATA_TYPE IN ( 'char', 'varchar', 'nchar', 'nvarchar ')
Taylor Brown

ApexSQL 검색은 훌륭한 도구입니다. 도구가 더러운 스크립트를 망칠 필요가없는 추상적 인 개념이기 때문에 이것이 최고의 대답이라고 생각합니다.
usefulBee 2012

또한 ApexSQL을 사용하면 일부 도구에 대한 비용을 지불 할 수 있지만이 도구는 무료입니다. 당신은 그들에게 당신의 이메일을 제공해야합니다. 훌륭한 도구입니다. 이것은 문서화되지 않은 타사 데이터베이스를 파고들 때 많은 도움이 될 것입니다. :)
youen

이것이 IMHO의 최고 답변이되어야합니다. 다른 데이터 유형을 필터링하는 기능은 훌륭합니다. 내가 가진 유일한 단점은 "검색 할 테이블"을 선택 / 선택 취소 하기위한 GUI가 NO 체크 / 체크 해제 옵션 또는 다중 선택 및 토글 기능 이있는 체크 박스 목록이라는 것입니다 . 따라서 모든 시스템 객체 (기본적으로 * 확인 * * 바보 같은)를 선택 취소하려면 공간 화살표 아래로 공간 화살표를 사용하십시오. . 그러나 고맙게도, 당신이 할 필요가 없을 정도로 효율적입니다. 그냥 검색하고 그 일을하십시오!
NateJ

ApexSQL 검색은 확실히 최고의 솔루션입니다. 방금 스크립트를 사용하여 데이터베이스에서 이메일 주소를 찾았습니다. 8:30 분 후에 포기했습니다. ApexSQL Search를 설치 한 후 정확히 동일한 문자열을 검색하여 11 개의 테이블에서 31 번 발견했습니다. 시간이 정확히 맞지는 않았지만 1 분도 채 걸리지
않았습니다

74

bnkdev의 답변을 바탕으로 Narayana의 코드 를 수정 하여 모든 열을 숫자 열까지 검색했습니다.

느리게 실행되지만이 버전은 실제로 텍스트 열에서 발견 된 것뿐만 아니라 모든 일치 항목을 찾습니다.

나는이 사람에게 충분히 감사 할 수 없다. 수작업으로 수일을 절약했습니다!

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

5
"고유 식별자 값을 char로 변환하기에 불충분 한 결과 공간"오류를 해결하기 위해 편집되었습니다. 이제는 XML 열에서도 작동합니다.
Chris

1
새로운 것이 있습니다 : 데이터 타입 이미지에서 varchar (max) 로의 명시 적 변환은 허용되지 않습니다. 나는 이것을 내 스스로 고치려고 노력할 것이지만 누군가 나를 때리면 알려주십시오. 감사합니다!
Taylor Brown

5
좋아, 방금 kd7의 코드에서 조각을 다시 추가하여 검색에서 해당 이미지 열을 남겨 두어 오류가 사라지는 데이터 유형을 검색했습니다 ... AND DATA_TYPE NOT IN ( 'image')
Taylor Brown

1
2014 SQL 서버에서 "목표 정렬 불가능 오류로 XML에서 하나 개 이상의 문자로 변환"을 얻기
Chetan에 메라에게

변수 유형마다 버전이 다를 수 있습니다. 그렇게하면 캐스팅하지 않고 더 빨리 실행됩니다. 파일 유형을 검색 가능한 유형과 비교할 수도 있습니다. 정수는 varchar 필드에있을 수 있습니다.
SQLMason 2016 년

38

이것은 내 자신의 작업에 사용하는이 질문에 대한 독립적 인 질문입니다. 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

수백 개의 DB에서 유지 관리하고 싶지 않기 때문에 proc 형식으로 작성하지 않으며 실제로 임시 작업을위한 것입니다. 버그 수정에 대해 의견을 주시기 바랍니다.


고맙지 만 phpMyAdmin에서 이것에 대한 구문 오류 만 얻습니다. 이것이 작성된 이후 SQL로 변경된 것이 있습니까?
NoBugs

3
@NoBugs SQL Server 용 T-SQL로 작성되었습니다.
Tim Lehner

@NoBugs : 자체 저장 프로시 저나 다른 함수 안에 코드를 캡슐화해야합니다.
Fandango68

2
결과를 명확히하기 위해 Microsoft SQL Server Management Studio에서이를 실행하면 검색어가 발견 된 경우에만 결과 탭이 열립니다. 검색어를 찾지 못하면 실행 된 검색어로 메시지 탭만 열립니다. 메시지 탭에는 결과가 포함되지 않지만 검색어를 찾으면 결과 탭과 함께 열립니다.
gakera

1
대단해! 사용자 지정 데이터베이스 개체를 스키마에 저장하지 않으려는 구매 한 앱으로 작업 감사!
Jeff

20

Allain Lalonde 답변을 최적화했습니다 ( https://stackoverflow.com/a/436676/412368 ). 숫자 값은 여전히 ​​지원됩니다. 대략 4-5 배 더 빨라야하며 (1:03 vs 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

5

이 질문을 해결하는 방법입니다. 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

4

정말 유용한 스크립트에 감사드립니다.

테이블에 변환 할 수없는 필드가있는 경우 코드에 다음 수정 사항을 추가해야합니다.

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
    )

크리스


3

얼마 전부터 계속 개선하고있는 해결책이 있습니다. 또한 지시가 있으면 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/


내 특권으로 작업하고 문자열뿐만 아니라 검색하여 내 테이블로 손상되지 않은 유일한 대답이었습니다.
Pedro Lacerda


2

여기에 매우 달콤하고 작은 해결책이 있습니다.

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';

1

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


1

당신이 열 이름을 포함하는 이름을 가진 모든 테이블을 얻으려면 가정 logintime 데이터베이스에 MYDATABASE 다음은 코드 샘플입니다

    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;

1

phpMyAdmin이 설치되어 있으면 검색 기능을 사용하십시오.

데이터베이스를 선택하십시오.

테이블이 아닌 데이터베이스를 선택했는지 확인하십시오. 그렇지 않으면 완전히 다른 검색 대화 상자가 나타납니다.

  1. 검색 탭을 클릭 하십시오
  2. 목록 항목 원하는 검색어를 선택하십시오
  3. 검색 할 테이블을 선택하십시오

0
-- 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 개의 검색 문자열이 있거나 검색 및 바꾸기 문자열이있는 것 같습니다. 검색 만하려면 원하는 문자열을 어디에 배치해야합니까?
SherylHohman

0

개발 목적으로 필요한 테이블 데이터를 단일 HTML로 내보내고 직접 검색 할 수 있습니다.


0

데이터베이스 클라이언트 도구 (예 : DBeaver 또는 phpMyAdmin )는 종종 전체 데이터베이스를 통한 전체 텍스트 검색 수단을 지원합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.