2009-11-25 49 views
82

Tôi có một giá trị cụ thể, giả sử chuỗi 'nhận xét'. Tôi cần phải tìm tất cả các trường hợp này trong cơ sở dữ liệu vì tôi cần cập nhật định dạng để thay đổi nó thành (*) Nhận xét.Tìm kiếm tất cả các bảng, tất cả các cột cho một giá trị cụ thể SQL Server

Làm thế nào tôi có thể làm điều này? Cơ sở dữ liệu ở định dạng SQL Server 2000.

+0

bạn có thể làm điều đó rất đơn giản với phpmyadmin – Matoeil

+0

Bạn có thể tìm thấy câu trả lời ở đây - http://stackoverflow.com/a/42714042/1820880 –

Trả lời

144

Tôi vừa cập nhật bài viết trên blog của tôi để sửa lỗi trong kịch bản mà bạn đã có Jeff, bạn sẽ nhìn thấy kịch bản cập nhật tại đây: Search all fields in SQL Server Database

Theo yêu cầu, đây là kịch bản trong trường hợp bạn muốn nó nhưng tôi khuyên bạn nên xem lại bài đăng trên blog như tôi cập nhật nó bất cứ lúc nào

DECLARE @SearchStr nvarchar(100) 
SET @SearchStr = '## YOUR STRING HERE ##' 
  
  
-- 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 
-- Updated and tested by Tim Gaunt 
-- http://www.thesitedoctor.co.uk 
-- http://blogs.thesitedoctor.co.uk/tim/2010/02/19/Search+Every+Table+And+Field+In+A+SQL+Server+Database+Updated.aspx 
-- Tested on: SQL Server 7.0, SQL Server 2000, SQL Server 2005 and SQL Server 2010 
-- Date modified: 03rd March 2011 19:00 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    DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal') 
       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 
  
DROP TABLE #Results 
+1

Trên thực tế, tôi đã cố gắng giải pháp trong bài đăng trên blog của bạn (nó có lỗi nhỏ), nhưng bằng cách nào đó, nó luôn trả về cùng một kết quả. Xem nhận xét của tôi trong bài đăng trên blog của bạn. – Abel

+0

Cảm ơn Abel, tôi đã có ý định khắc phục điều đó, tôi đã đưa ra hai hương vị, một thứ có thể chạy trên chính nó mà không cần tạo một thủ tục lưu sẵn, quy trình còn lại là thủ tục lưu trữ có thể sử dụng lại được đã được thêm vào db của bạn, bạn có thể chạy lại bất cứ lúc nào bạn muốn. Hy vọng điều đó sẽ hữu ích. Tim – Tim

+0

Kịch bản tuyệt vời, Tim. Tôi chỉ thêm hỗ trợ uniqueidentifier cho phù hợp với nhu cầu của tôi, nhưng nó vẫn hoạt động như một sự quyến rũ. – anthares

2

Bạn có thể truy vấn chế độ xem cơ sở dữ liệu sys.tables để lấy tên của các bảng và sau đó sử dụng truy vấn này để tự xây dựng một truy vấn khác để thực hiện cập nhật ở mặt sau của điều đó. Ví dụ:

select 'select * from '+name from sys.tables 

sẽ cung cấp cho bạn một kịch bản mà sẽ chạy select * chống lại tất cả các bảng trong danh mục hệ thống, bạn có thể làm thay đổi chuỗi trong mệnh đề select để làm cập nhật của bạn, miễn là bạn biết tên cột là như nhau trên tất cả các bảng bạn muốn cập nhật, vì vậy kịch bản của bạn sẽ giống như thế:

select 'update '+name+' set comments = ''(*)''+comments where comments like ''%comment to be updated%'' ' from sys.tables 

bạn cũng có thể sau đó predicate trên các bảng truy vấn để chỉ bao gồm các bảng có một tên trong một định dạng nhất định , hoặc trong một tập con bạn muốn tạo tập lệnh cập nhật.

4

dưới đây Query hoạt động nhưng rất chậm ... sao chép từ vyaskn.tripod.com

Declare @SearchStr nvarchar(100) 

SET @SearchStr='Search String' BEGIN 

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 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 
40

tôi công bố một ở đây: FullParam SQL Blog

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

Cảm ơn bạn. Làm việc hoàn hảo cho tôi. Nhanh hơn nhiều so với thủ tục 'SearchAllTables' được tìm thấy trong chuỗi này. – krdx

+2

Hoạt động như một sự quyến rũ. – contactmatt

+1

Đã dành cho tôi rất nhiều thời gian khi cố gắng tìm ra nơi mà một số giá trị đã được lưu, cảm ơn một nhóm! Làm việc với SQL Server 2014. –

Các vấn đề liên quan