Tìm một giá trị ở bất cứ đâu trong cơ sở dữ liệu


253

Đưa ra một #, làm thế nào để tôi khám phá trong bảng và cột nào có thể được tìm thấy trong đó?

Tôi không quan tâm nếu nó nhanh, nó chỉ cần làm việc.


1
Bạn muốn tìm kiếm tất cả các cột / hàng cho một số cụ thể? Bạn có thể giới hạn nó vào các cột số? Cột số nguyên? Cột danh tính?
Michael Haren

1
tất cả các cột sẽ là tốt nhất, nhưng số sẽ làm. Cột thụt quá cụ thể
Allain Lalonde

1
Bạn có thể phải viết một tập lệnh ngắn để truy vấn siêu dữ liệu (trong trường hợp này là danh sách các bảng / cột) từ cơ sở dữ liệu và đưa ra một loạt các câu lệnh chọn tìm giá trị.
Draemon

9
Điều này là cổ xưa, nhưng tại sao không chỉ làm một bãi chứa và grep bãi rác?
baordog

3
phpmyadmin cho phép điều này rất đơn giản
Matoeil

Câu trả lời:


284

Điều này có thể giúp bạn . - từ Narayana Vyas. Nó tìm kiếm tất cả các cột của tất cả các bảng trong một cơ sở dữ liệu nhất định. Tôi đã sử dụng nó trước đây và nó hoạt động.

Đây là Proc được lưu trữ từ liên kết trên - thay đổi duy nhất tôi đã thực hiện là thay thế bảng tạm thời cho một biến bảng để bạn không phải nhớ bỏ nó mỗi lần.

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 script này chỉ tìm kiếm các trường văn bản, không phải các trường số. Trong trường hợp của tôi, nó hoạt động được vì các nhà phát triển đã lưu trữ một số trong một varchar, nhưng nói chung việc tìm kiếm các số sẽ không hoạt động.
Allain Lalonde

1
Chúng ta có thể làm điều này bằng một truy vấn duy nhất thay vì sử dụng một thủ tục được lưu trữ không?
Freakyuser

6
Làm thế nào ai đó có thể bản quyền một thủ tục sql đơn giản? nó gây trở ngại cho tôi
David Andrei Ned

3
@DavidAndreiNed, anh ấy không thể, ít nhất là không có cách nào anh ấy đã làm. Tôi không chắc liệu đây có phải là trường hợp trở lại vào năm 2009 hay không, nhưng ngày nay, câu trả lời là CC-BY-SA 3.0
Arturo Torres Sánchez

2
Tôi nên đặt chuỗi mà tôi muốn tìm ở đâu trong đoạn script? trong tập @ SearchStr2?
Randy Quackers

77

Nếu bạn chỉ cần chạy tìm kiếm như vậy một lần thì có lẽ bạn có thể đi với bất kỳ tập lệnh nào đã được hiển thị trong các câu trả lời khác. Nhưng nếu không, tôi khuyên bạn nên sử dụng ApexSQL Search cho việc này. Đó là một addin SSMS miễn phí và nó thực sự giúp tôi tiết kiệm rất nhiều thời gian.

Trước khi chạy bất kỳ tập lệnh nào, bạn nên tùy chỉnh nó dựa trên kiểu dữ liệu bạn muốn tìm kiếm. Nếu bạn biết bạn đang tìm kiếm cột datetime thì không cần phải tìm kiếm qua các cột nvarchar. Điều này sẽ tăng tốc tất cả các truy vấn ở trên.


1
Tôi đã mất một lúc để tìm ra nơi để làm điều này, bất cứ ai đọc nhận xét này đều có thể thực hiện được trong truy vấn bằng cách thay đổi đoạn này từ câu trả lời được chấp nhận: AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar ')
Taylor Brown

ApexSQL Search là một công cụ tuyệt vời. Tôi nghĩ rằng đây nên là câu trả lời hàng đầu vì một công cụ là một khái niệm trừu tượng không liên quan đến việc gây rối với các tập lệnh bẩn.
hữu íchBee

Cũng lưu ý rằng trong khi ApexSQL khiến bạn phải trả tiền cho một số công cụ của họ, thì công cụ này là miễn phí. Bạn chỉ cần cung cấp cho họ email của bạn. Một công cụ tuyệt vời, điều này sẽ giúp tôi rất nhiều khi đào sâu vào cơ sở dữ liệu của bên thứ 3 không có giấy tờ :)
youen

Đây phải là câu trả lời hàng đầu, IMHO. Khả năng lọc trên các kiểu dữ liệu khác nhau là rất tốt. Nắm bắt duy nhất tôi có về nó, đó là GUI để chọn / bỏ chọn "bảng nào cần tìm trong" là một danh sách hộp kiểm với tùy chọn KHÔNG kiểm tra / bỏ chọn-TẤT CẢ hoặc khả năng đa lựa chọn và chuyển đổi. Vì vậy, nếu bạn muốn, không kiểm tra tất cả các đối tượng hệ thống (được * kiểm tra * theo mặc định, đó là ngớ ngẩn), bạn phải thực hiện một bài tập không gian-mũi tên xuống không gian-mũi tên * quảng cáo * quảng cáo * . Nhưng may mắn thay, nó đủ hiệu quả mà bạn không phải làm. Chỉ cần để nó tìm kiếm và làm điều của nó!
NateJ

ApexSQL Search chắc chắn là giải pháp tốt nhất. Tôi vừa thử sử dụng tập lệnh để tìm địa chỉ email trong cơ sở dữ liệu - 8:30 phút sau, tôi đã bỏ cuộc. Sau khi cài đặt ApexQuery Search, tôi đã tìm kiếm chính xác cùng một chuỗi và nó đã tìm thấy nó 31 lần trong 11 bảng. Tôi đã không tính thời gian một cách chính xác, nhưng chỉ mất chưa đến một phút
trực tuyến

74

Dựa trên câu trả lời của bnkdev, tôi đã sửa đổi Mã của Narayana để tìm kiếm tất cả các cột ngay cả số cột.

Nó sẽ chạy chậm hơn, nhưng phiên bản này thực sự tìm thấy tất cả các kết quả khớp không chỉ những cái được tìm thấy trong các cột văn bản.

Tôi không thể cảm ơn anh chàng này đủ. Tiết kiệm cho tôi ngày tìm kiếm bằng tay!

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
được chỉnh sửa để giải quyết lỗi "Không đủ kết quả không gian để chuyển đổi giá trị định danh duy nhất thành char". Điều này bây giờ cũng sẽ làm việc cho các cột XML.
Chris

1
đây là một cái mới: Không được phép chuyển đổi rõ ràng từ hình ảnh kiểu dữ liệu sang varchar (max). Tôi sẽ tự mình thử và sửa nó, nhưng nếu ai đó đánh bại tôi thì hãy cho tôi biết, cảm ơn!
Taylor Brown

5
Ok, tôi vừa thêm lại một đoạn từ mã của kd7 để chỉ tìm kiếm các kiểu dữ liệu mà tôi đang tìm sẽ khiến các cột hình ảnh đó rời khỏi tìm kiếm của tôi khiến lỗi biến mất ... VÀ DATA_TYPE KHÔNG IN ('hình ảnh')
Taylor Brown

1
Nhận "Chuyển đổi một hoặc nhiều ký tự từ XML sang lỗi không thể đối chiếu đích" trong máy chủ SQL 2014.
Chetan Mehra

Bạn chỉ có thể có các phiên bản khác nhau cho các loại biến khác nhau. Bằng cách đó, bạn không truyền và nó sẽ chạy nhanh hơn. Bạn cũng có thể so sánh các loại tệp để tìm kiếm các loại có thể sử dụng. Một số nguyên có thể là trong một trường varchar.
SQLMason

38

Đây là cách độc lập của tôi đối với câu hỏi này mà tôi sử dụng cho công việc của mình. Nó hoạt động trong SQL2000 trở lên, cho phép ký tự đại diện, lọc cột và sẽ tìm kiếm hầu hết các loại dữ liệu thông thường.

Một mô tả mã giả có thể là 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

Tôi không đặt nó ở dạng Proc vì tôi không muốn duy trì nó trên hàng trăm DB và dù sao nó cũng thực sự dành cho công việc đặc biệt. Xin vui lòng bình luận về sửa lỗi.


Cảm ơn, nhưng tôi không nhận được gì ngoài lỗi cú pháp về điều này trong phpMyAdmin. Có điều gì đó đã thay đổi với SQL kể từ khi nó được viết?
NoBugs

3
@NoBugs Điều này được viết bằng T-SQL cho SQL Server.
Tim Lehner

@NoBugs: Bạn cần đóng gói mã bên trong thủ tục được lưu trữ của riêng bạn hoặc một số chức năng khác.
Fandango68

2
Chỉ cần làm rõ đầu ra, nếu chạy nó từ Microsoft SQL Server Management Studio, tab Kết quả sẽ chỉ bật mở nếu tìm thấy cụm từ tìm kiếm. Nếu không tìm thấy cụm từ tìm kiếm, chỉ có tab Tin nhắn sẽ mở với các câu lệnh tìm kiếm được thực hiện. Tab Tin nhắn không bao gồm bất kỳ kết quả nào nhưng cũng sẽ mở cùng với tab Kết quả khi tìm thấy cụm từ tìm kiếm.
gakera

1
Điều đó thật tuyệt! Làm việc với một ứng dụng đã mua trong đó tôi không muốn lưu các đối tượng cơ sở dữ liệu tùy chỉnh vào lược đồ của chúng. Cảm ơn!
Jeff

20

Tôi đã tối ưu hóa câu trả lời của Allain Lalonde ( https://stackoverflow.com/a/436676/412368 ). Giá trị số vẫn được hỗ trợ. Phải nhanh hơn khoảng 4-5 lần (1:03 so với 4:30), được thử nghiệm trên máy tính để bàn với cơ sở dữ liệu 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

Đó là cách của tôi để giải quyết câu hỏi này. Đã thử nghiệm trên 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

Cảm ơn kịch bản thực sự hữu ích.

Bạn có thể cần thêm sửa đổi sau vào mã nếu các bảng của bạn có các trường không thể chuyển đổi:

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
    )

Chris


3

Tôi có một giải pháp từ một thời gian trước đây mà tôi tiếp tục cải thiện. Cũng tìm kiếm trong các cột XML nếu được yêu cầu làm như vậy hoặc tìm kiếm các giá trị nguyên nếu cung cấp một chuỗi số nguyên.

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

Nguồn: http://fullparam.wordpress.com/2012/09/07/fck-it-i-am-ftime-to-search-all-tables-all-collumns/


Đó là câu trả lời duy nhất hoạt động với các đặc quyền của tôi, tìm kiếm không chỉ các chuỗi và không bị phá vỡ với các bảng của tôi.
Pedro Lacerda


2

Đây, giải pháp rất ngọt và nhỏ:

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

Một cách khác bằng cách sử dụng THAM GIA và HIỆN TẠI:

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

Giả sử nếu bạn muốn lấy tất cả các bảng có tên một tên cột chứa logintime trong cơ sở dữ liệu MyDatabase bên dưới là mẫu mã

    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

Nếu bạn đã cài đặt phpMyAdmin, hãy sử dụng Tìm kiếm của nó tính năng .

Chọn DataBase của bạn.

Hãy chắc chắn rằng bạn đã chọn DataBase, không phải bảng, nếu không, bạn sẽ nhận được hộp thoại tìm kiếm hoàn toàn khác.

  1. Bấm Tìm kiếm tab
  2. Danh sách mục Chọn thuật ngữ tìm kiếm bạn muốn
  3. Chọn các bảng để tìm kiếm

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

Tôi không rõ làm thế nào điều này hoạt động. Có vẻ như có 2 chuỗi tìm kiếm, hoặc một chuỗi tìm kiếm và thay thế? Nếu tôi chỉ muốn tìm kiếm, tôi sẽ đặt chuỗi tôi đang tìm ở đâu?
SherylHohman

0

Đối với mục đích Phát triển, bạn chỉ có thể xuất dữ liệu bảng cần thiết thành một HTML duy nhất và thực hiện tìm kiếm trực tiếp trên đó.


0

Các công cụ máy khách cơ sở dữ liệu (như DBeaver hoặc phpMyAdmin ) thường hỗ trợ các phương tiện tìm kiếm toàn văn bản thông qua toàn bộ cơ sở dữ liệu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.