2017-05-08 36 views
1

我想知道是否有方法可以查看所有數據庫以及SQL中存在特定字符串的對應表Server 2012.在SQL SERVER中的所有數據庫中搜索字符串並列出所有數據庫,表和相應的列

我能夠通過使用我在網上找到的存儲過程來搜索特定數據庫中所有表中的字符串。但我想在所有數據庫中搜索它。

CREATE PROC SearchAllTables 
(
@SearchStr nvarchar(100) 
) 
AS 
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', '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 + 'WITH (NOLOCK) ' + 
        ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
       ) 
      END 
     END  
    END 

    SELECT ColumnName, ColumnValue FROM #Results 
END 

而當我執行下面的查詢時,它會列出所有表以及列名。

exec SearchAllTables "B2" 

OUTPUT:

 ColumnName    ColumnValue 
[dbo].[msm_temp].[molecule_nm] B2 
[dbo].[msm_temp1].[molecule_nm] B2 
[dbo].[msm_temp2].[molecule_nm] B2 
[dbo].[msm_temp3].[molecule_nm] B2 
[dbo].[msm_temp4].[molecule_nm] B2 

任何幫助表示讚賞。

+0

請參閱[此問題](http://stackoverflow.com/questions/147659/get-list-of-databases-from-sql-server)的答案,瞭解如何枚舉服務器上的所有數據庫。從那裏應該很容易修改你的查詢。 –

+0

您是否在嘗試查找對特定列的所有引用? – Sparrow

+0

@Sparrow是的字符串出現的所有引用都很有用。 – SVK

回答

2

您可以使用此存儲過程與價值的搜索是這樣的:

exec SearchAllDatabases @SearchTerm = '%B2%' 

這可以幫助你到處搜尋,但如果你在你的數據庫中太多的數據,這將需要時間來執行。

存儲過程:

CREATE PROCEDURE dbo.SearchAllDatabases 
    @SearchTerm NVARCHAR(255) = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 

IF @SearchTerm IS NULL OR @SearchTerm NOT LIKE N'%[^%^_]%' 
    BEGIN 
    RAISERROR(N'Please enter a valid search term.', 11, 1); 
RETURN; 
    END 

    CREATE TABLE #results 
    (
    [database] SYSNAME, 
    [schema]  SYSNAME, 
    [table]  SYSNAME, 
    [column]  SYSNAME, 
    ExampleValue NVARCHAR(1000) 
); 

    DECLARE 
    @DatabaseCommands NVARCHAR(MAX) = N'', 
    @ColumnCommands NVARCHAR(MAX) = N''; 

    SELECT @DatabaseCommands = @DatabaseCommands + N' 
    EXEC ' + QUOTENAME(name) + '.sys.sp_executesql 
     @ColumnCommands, N''@SearchTerm NVARCHAR(MAX)'', @SearchTerm;' 
    FROM sys.databases 
    WHERE database_id > 4 -- non-system databases 
     AND[state]  = 0-- online 
     AND user_access = 0; -- multi-user 

    SET @ColumnCommands = N'DECLARE @q NCHAR(1), 
      @SearchCommands NVARCHAR(MAX); 

SELECT @q = NCHAR(39), 
    @SearchCommands = N''DECLARE @VSearchTerm VARCHAR(255) = @SearchTerm;''; 

    SELECT @SearchCommands = @SearchCommands + CHAR(10) + N'' 

     SELECT TOP(1) 
     [db]  = DB_NAME(), 
     [schema] = N'' + @q + s.name + @q + '', 
     [table] = N'' + @q + t.name + @q + '', 
     [column] = N'' + @q + c.name + @q + '', 
     ExampleValue = LEFT('' + QUOTENAME(c.name) + '', 1000) 
     FROM '' + QUOTENAME(s.name) + ''.'' + QUOTENAME(t.name) + '' 
     WHERE '' + QUOTENAME(c.name) + N'' LIKE @'' + CASE 
     WHEN c.system_type_id IN(35, 167, 175) THEN ''V'' 
     ELSE '''' END + ''SearchTerm;'' 

    FROM sys.schemas AS s 
    INNER JOIN sys.tables AS t 
    ON s.[schema_id] = t.[schema_id] 
    INNER JOIN sys.columns AS c 
    ON t.[object_id] = c.[object_id] 
    WHERE c.system_type_id IN (35, 99, 167, 175, 231, 239) 
     AND c.max_length >= LEN(@SearchTerm); 

PRINT @SearchCommands; 
EXEC sys.sp_executesql @SearchCommands, 
    N''@SearchTerm NVARCHAR(255)'', @SearchTerm;'; 

    INSERT #Results 
    (
    [database], 
    [schema], 
    [table], 
    [column], 
    ExampleValue 
) 
    EXEC[master].sys.sp_executesql @DatabaseCommands, 
    N'@ColumnCommands NVARCHAR(MAX), @SearchTerm NVARCHAR(255)', 
    @ColumnCommands, @SearchTerm; 

    SELECT[Searched for] = @SearchTerm; 

    SELECT[database],[schema],[table],[column],ExampleValue 
FROM #Results 
    ORDER BY[database],[schema],[table],[column]; 
END 
GO 

我希望這可以幫助你。

+0

此查詢工作正常,但需要很長時間。有沒有優化的解決方案? – SVK

+0

我不確定兄弟。但我試圖優化這一點。因爲我也需要這個在我的數據庫中搜索。如果這對你有效,你喜歡接受它。 –

+0

此腳本也會引發此錯誤:SQL Server數據庫錯誤:參數數據類型文本對於左函數的參數1無效。 – SVK

相關問題