ค้นหาค่าได้ทุกที่ในฐานข้อมูล


253

ระบุ # ฉันจะค้นพบในตารางและคอลัมน์ใดได้ภายใน

ฉันไม่สนใจว่ามันจะเร็วแค่ไหนก็ต้องทำงาน


1
คุณต้องการค้นหาจำนวนคอลัมน์ / แถวทั้งหมดหรือไม่ คุณสามารถ จำกัด เฉพาะคอลัมน์ที่เป็นตัวเลขได้หรือไม่ คอลัมน์จำนวนเต็มหรือไม่ คอลัมน์ตัวตน?
ไมเคิลฮาเรน

1
คอลัมน์ทั้งหมดจะดีที่สุด แต่จะเป็นตัวเลข คอลัมน์การเยื้องนั้นเจาะจงเกินไป
Allain Lalonde

1
คุณอาจต้องเขียนสคริปต์สั้น ๆ เพื่อสืบค้นข้อมูลเมตา (ในกรณีนี้คือรายการของตาราง / คอลัมน์) จากฐานข้อมูลและออกชุดคำสั่งที่เลือกเพื่อค้นหาค่า
Draemon

9
นี่คือโบราณ แต่ทำไมไม่เพียงแค่ถ่ายโอนข้อมูลและ grep การถ่ายโอนข้อมูล
baordog

3
phpmyadmin อนุญาตให้ทำได้อย่างง่ายดายมาก
Matoeil

คำตอบ:


284

สิ่งนี้อาจช่วยคุณได้ - จาก Narayana Vyas มันค้นหาคอลัมน์ทั้งหมดของตารางทั้งหมดในฐานข้อมูลที่กำหนด ฉันเคยใช้มาก่อนและใช้งานได้

นี่คือ Stored Proc จากลิงก์ด้านบน - การเปลี่ยนแปลงอย่างเดียวที่ฉันทำคือการแทนที่ตาราง temp สำหรับตัวแปรตารางดังนั้นคุณไม่ต้องจำที่จะทิ้งมันในแต่ละครั้ง

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
FYI สคริปต์นี้ค้นหาเฉพาะฟิลด์ข้อความไม่ใช่ฟิลด์ตัวเลข ในกรณีของฉันมันทำงานได้เพราะ devs กำลังจัดเก็บตัวเลขใน varchar แต่โดยทั่วไปการหาตัวเลขจะไม่ทำงาน
Allain Lalonde

1
เราสามารถทำได้โดยใช้แบบสอบถามเดียวแทนที่จะใช้กระบวนงานที่เก็บไว้?
Freakyuser

6
ใครบางคนสามารถจดลิขสิทธิ์ขั้นตอนง่ายๆของ SQL ได้? มันทำให้ฉันงงงัน
David Andrei Ned

3
@DavidAndreiNed เขาทำไม่ได้อย่างน้อยก็ไม่มีวิธีที่เขาทำ ฉันไม่แน่ใจว่าเป็นกรณีนี้ในปี 2009 แต่ทุกวันนี้คำตอบคือ CC-BY-SA 3.0
Arturo Torres Sánchez

2
ฉันควรวางสตริงที่ฉันต้องการค้นหาที่ไหนในสคริปต์ ใน set @ SearchStr2 หรือไม่
Randy Quackers

77

หากคุณต้องการเรียกใช้การค้นหาดังกล่าวเพียงครั้งเดียวคุณสามารถใช้สคริปต์ใด ๆ ที่แสดงในคำตอบอื่นได้แล้ว แต่อย่างอื่นฉันขอแนะนำให้ใช้ApexSQL Searchสำหรับสิ่งนี้ มันเป็นโปรแกรมเสริม SSMS ฟรีและช่วยฉันได้มากจริงๆ

ก่อนเรียกใช้สคริปต์ใด ๆ คุณควรปรับแต่งตามชนิดข้อมูลที่คุณต้องการค้นหา หากคุณรู้ว่าคุณกำลังค้นหาคอลัมน์วันที่และเวลาไม่จำเป็นต้องค้นหาผ่านคอลัมน์ nvarchar วิธีนี้จะทำให้การสืบค้นทั้งหมดข้างต้นเร็วขึ้น


1
เอาฉันสักครู่เพื่อคิดออกว่าจะทำอย่างไรใครที่อ่านความคิดเห็นนี้สามารถทำได้ในแบบสอบถามโดยการแก้ไขชิ้นนี้จากคำตอบที่ยอมรับ: และ DATA_TYPE ใน ('ถ่าน', 'varchar', 'nchar', 'nvarchar ')
Taylor Brown

ApexSQL Search เป็นเครื่องมือที่ยอดเยี่ยม ฉันคิดว่านี่ควรเป็นคำตอบที่ดีที่สุดเนื่องจากเครื่องมือเป็นแนวคิดเชิงนามธรรมที่ไม่เกี่ยวข้องกับการยุ่งกับสคริปต์ที่สกปรก
UsefulBee

นอกจากนี้โปรดทราบว่าในขณะที่ ApexSQL ทำให้คุณจ่ายเงินสำหรับเครื่องมือบางอย่างเครื่องมือนี้ไม่มีค่าใช้จ่าย คุณเพียงแค่ต้องให้อีเมลของพวกเขา เครื่องมือที่ดีเยี่ยมนี้เป็นจะช่วยเหลือฉันมากเมื่อขุดในฐานข้อมูลของบุคคลที่ 3 ที่ไม่มีเอกสาร :)
youen

นี่ควรเป็นคำตอบที่ดีที่สุด IMHO ความสามารถในการกรองประเภทข้อมูลต่าง ๆ นั้นยอดเยี่ยม สิ่งเดียวที่ฉันมีเกี่ยวกับมันคือ GUI สำหรับการเลือก / ยกเลิกการเลือก "สิ่งที่ตารางที่จะค้นหา" เป็นรายการที่มีช่องทำเครื่องหมายไม่มีตัวเลือกตรวจสอบ / ไม่เลือกทั้งหมดหรือความสามารถในการเลือกและสลับหลาย ดังนั้นถ้าคุณต้องการที่จะพูดยกเลิกการตรวจสอบวัตถุระบบทั้งหมด (ซึ่งเป็น * การตรวจสอบ * โดยค่าเริ่มต้นซึ่งเป็นโง่) คุณจะต้องผ่านพื้นที่-arrowdown-space-arrowdown * ad-nauseum * แบบฝึกหัด . แต่โชคดีที่มันมีประสิทธิภาพเพียงพอที่คุณไม่จำเป็นต้องทำ เพียงปล่อยให้มันค้นหาและทำสิ่งนั้น!
NateJ

ApexSQL Search เป็นทางออกที่ดีที่สุดอย่างแน่นอน ฉันเพิ่งลองใช้สคริปต์เพื่อค้นหาที่อยู่อีเมลในฐานข้อมูล - 8:30 นาทีหลังจากนั้นฉันก็เลิก หลังจากติดตั้ง ApexSQL Search ฉันค้นหาสตริงเดียวกันทั้งหมดและพบ 31 ครั้งใน 11 ตาราง ฉันไม่ได้เวลาที่มันถูกต้อง แต่มันต้องใช้เวลาน้อยกว่าหนึ่งนาที
cyberspy

74

จากคำตอบของ bnkdev ฉันได้แก้ไขCode ของ 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
แก้ไขเพื่อแก้ไขข้อผิดพลาด "พื้นที่ผลลัพธ์ไม่เพียงพอในการแปลงค่าตัวระบุเฉพาะเป็นถ่าน" สิ่งนี้จะทำงานกับคอลัมน์ XML ได้เช่นกัน
Chris

1
นี่คือรูปแบบใหม่: ไม่อนุญาตการแปลงที่ชัดเจนจากอิมเมจชนิดข้อมูลเป็น varchar (สูงสุด) ฉันจะพยายามและแก้ไขปัญหานี้ด้วยตัวเอง แต่ถ้ามีคนชนะฉันเพื่อแจ้งให้ฉันทราบขอบคุณ!
Taylor Brown

5
ตกลงฉันเพิ่งเพิ่มชิ้นส่วนจากรหัสของ kd7 เพื่อค้นหาประเภทข้อมูลที่ฉันต้องการซึ่งจะทำให้คอลัมน์ภาพเหล่านั้นหลุดจากการค้นหาทำให้เกิดข้อผิดพลาดหายไป ... และ DATA_TYPE ไม่ได้อยู่ใน 'ภาพ')
Taylor Brown

1
ได้รับ "การแปลงหนึ่งหรือมากกว่าหนึ่งตัวอักษรจาก XML เป็นข้อผิดพลาดที่เป็นไปไม่ได้ของการเรียงเป้าหมาย" ใน SQL Server 2014
Chetan Mehra

คุณสามารถมีรุ่นที่แตกต่างกันสำหรับประเภทตัวแปรที่แตกต่างกัน ด้วยวิธีนี้คุณไม่ได้กำลังส่งและจะทำงานเร็วขึ้น นอกจากนี้คุณยังสามารถเปรียบเทียบประเภทไฟล์เพื่อค้นหาประเภทที่สามารถบล็อกได้ จำนวนเต็มอาจอยู่ในฟิลด์ varchar
SQLMason

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

ฉันไม่ได้ใส่มันในรูปแบบ proc เพราะฉันไม่ต้องการที่จะเก็บรักษาไว้ในฐานข้อมูลนับร้อยและมันก็เป็นงานโฆษณาจริง ๆ โปรดแสดงความคิดเห็นเกี่ยวกับการแก้ไขข้อผิดพลาด


ขอบคุณ แต่ฉันไม่ได้รับอะไรนอกจากข้อผิดพลาดทางไวยากรณ์ใน phpMyAdmin มีบางสิ่งเปลี่ยนแปลงกับ SQL นับตั้งแต่มีการเขียนขึ้นมาใช่หรือไม่
NoBugs

3
@NoBugs นี่เป็นลายลักษณ์อักษรใน T-SQL สำหรับ SQL Server
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 กับ 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 และเคอร์เซอร์:

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.