2016-08-08 11 views
1

編集:この質問は重複としてフラグが設定されていますが、そうではありません。それでその他の答えは、どのように単一のデータベース内のすべてのテーブルを検索するかを示しています。私は、特定のサーバ上のすべてのデータベースのすべてのテーブルを検索する必要があります。サーバー上のすべてのデータベースのすべてのテーブルで文字列を検索します。

サーバー上のすべてのデータベースに対して検索文字列を検索する必要があります。私は、ドメイン全体が変化しているテーブル全体に電子メールアドレスが散在しているので、これらの電子メールアドレスの場所を示すレポートを準備する必要があります。私はすべてのデータベースにストアドプロシージャを追加することができないため、spを繰り返し実行することを伴わないクエリを実行する必要があります。私はthe netからこのコードを取り出し、すべてのテーブルを検索するためにそれを使用していましたが、すべてのデータベースでそれを実行する方法を理解できませんでした。

drop table #Results 
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630)) 

SET NOCOUNT ON 

DECLARE @SearchStr nvarchar(100), @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) 
SET @SearchStr = '@domaintobereplaced.com' 
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 top 10 ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
       FROM ' + @TableName + ' (NOLOCK) ' + 
       ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
      ) 
     END 
    END 
END 

SELECT ColumnName, ColumnValue FROM #Results 
+0

サーバーにphpmyadminがインストールされていますか? – brad

+0

あなたのSQLサーバで 'sp_MSforeachdb'を見つけて、直接使用するか、そのコードを見てください。 – Serg

+0

私はSQLサーバ管理スタジオを持っていますが、PHPのmyadmin –

答えて

0

この質問は、この時点では少し古いですと回答のほとんどは、すべてのサーバーと、各サーバー上のすべてのデータベースを検索するという点でマークを欠場するようです。私のマネージャーは、私たちのチームが組織内で解散しようとしており、私たちはすべて会社内のさまざまな場所に派遣されていたので、私には不可能で時間のかかる作業、

包括的な答えを書くために、ここではコンマで区切られたサーバー名のリストを受け入れるコンソールアプリケーションを作成する方法をとっています。すべてのサーバー名をループして1つずつ接続します。一旦サーバーに入ったら、ユーザーが作成したすべてのデータベースを照会してループし、それぞれのすべてのテーブルの検索を実行します。結果が見つかったら、[ServerName] _ [DatabaseName] _Resultsタイトルのディレクトリに保存されているファイルにそれらを書き出し、出力されたファイルの一覧を使用して、追加のクエリ/修復のためのレビューと開発、およびアクションプランを作成します。 SQL Serverでこれを行う方法があるという上記の答えからは現れません。

1

まず、すべてのデータベース名のリストをsys.databasesから収集する必要があります。
そして、あなたは、あなたがそれのすべてを取得する場合[database].[schema].[table name]'. You can do it by linking following tables:のような形式で、すべてのデータベース内のすべてのテーブルの名前を抽出するために、[データベース] .sys.schemas' & [database].sys.tables'<BR/> Then you get list of all text columns by linking found tables to [データベース] .sys.columns'
を、動的SQLを作成する必要がありますすべてのテーブルとテキスト列に対して動的なクエリを作成できます。

BTW誰かがTEXT列の中のデータを隠す場合は、それを検索に含めて変換する必要があります。

0

私が書いたvb.netのコードだとわかりませんが、テーブルとフィールドが見つかり、潜在的にすべてのDBを検索しています - それは単なる調査援助で、フィールドタイプを追加しました彼らが巻き起こってきましたが、私は、これは、ここで1時間の事であるカーソルのアプローチに代わるものであると仮定すると、とにかく

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 

    Dim scon As String = String.Format("Data Source={0};Initial Catalog=MASTER;Integrated Security=True", cmbInstance.SelectedItem.ToString) 

    Button1.Enabled = False 
    Dim Matches As New List(Of Locator) 

    With ListVresults 

     .Clear() 

     .View = View.Details 


     .Columns.Add("Database", 200) 
     .Columns.Add("Table", 200) 
     .Columns.Add("Field", 200) 

    End With 


    Using con As New SqlConnection(scon), 
      da As New SqlDataAdapter("select *, SCHEMA_NAME(schema_id) as SkeemaName from sys.tables where type = 'U'", con), 
      daDB As New SqlDataAdapter("select * from sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb') and state = 0 ORDER BY NAME", con), 
      dtDB As New DataTable 

     Dim UseLike As Boolean = chkLIKE.Checked 
     Dim CompOperator As String = If(chkLIKE.Checked, "LIKE", "=") 

     con.Open() 


     daDB.Fill(dtDB) 

     For Each drdb As DataRow In dtDB.Select(If(cmbDB.SelectedIndex = 0, "", String.Format("name = '{0}'", cmbDB.SelectedItem.ToString)), "name") 
      'For Each drdb As DataRow In dtDB.Rows 

      con.ChangeDatabase(drdb!name.ToString) 

      Using dt As New DataTable 
       da.Fill(dt) 
       For Each dr As DataRow In dt.Select("", "name") 
        lblProc.Text = String.Format("({2} - {0} - {1}", drdb!name.ToString, dr!name.ToString, Matches.Count) 
        Application.DoEvents() 
        Dim sql As New System.Text.StringBuilder 
        Using dsDatNull As New DataSet, 
         daDatNull As New SqlDataAdapter(String.Format("SELECT * FROM [{0}].[{1}] WHERE 1=0; SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{0}' AND TABLE_NAME = '{1}'", dr!skeemaName, dr!name), con) 

         daDatNull.Fill(dsDatNull) 

         'SELECT * FROM(INFORMATION_SCHEMA.COLUMNS) WHERE TABLE_NAME = 'absence' 

         sql.AppendFormat("SELECT * FROM [{0}].[{1}] WHERE ", dr!skeemaname, dr!name) 



         Dim bOR As Boolean = False 

         Dim col As DataColumn 
         Dim Q As System.Data.EnumerableRowCollection(Of System.Data.DataRow) = (From x As DataRow In dsDatNull.Tables(1) Where String.Compare(x!column_name.ToString, col.ColumnName, True) = 0 Select x) 

         For Each col In dsDatNull.Tables(0).Columns 

          Dim drColType As DataRow = Q(0) 
          Dim dataType As String = drColType!Data_Type.ToString 


          If "x".GetType Is col.DataType AndAlso (String.Compare(dataType, "nvarchar", True) = 0 _ 
                     OrElse String.Compare(dataType, "varchar", True) = 0 _ 
                     OrElse String.Compare(dataType, "nchar", True) = 0 _ 
                     OrElse String.Compare(dataType, "char", True) = 0) Then 



           If bOR Then sql.Append(" OR ") 
           bOR = True 
           sql.Append("[" + col.ColumnName + "]").Append(If(UseLike, " LIKE ", " = ")).AppendFormat("'{0}{1}{2}'", If(UseLike, "%", ""), txtCode.Text.Replace("'", "''"), If(UseLike, "%", "")) 


          ElseIf (New Guid).GetType Is col.DataType Then 

           If bOR Then sql.Append(" OR ") 
           bOR = True 
           sql.Append("cast([" + col.ColumnName + "] as nvarchar(80))").Append(If(UseLike, " LIKE ", " = ")).AppendFormat("'{0}{1}{2}'", If(UseLike, "%", ""), txtCode.Text.Replace("'", "''"), If(UseLike, "%", "")) 


          End If 

         Next 

         If Not bOR Then sql.Append(" 1=0 ") 

        End Using 



        Using dtDat As New DataTable, 
         daDat As New SqlDataAdapter(sql.ToString, con) 
         daDat.SelectCommand.CommandTimeout = 3600 

         daDat.Fill(dtDat) 

         For Each drDat As DataRow In dtDat.Rows 
          For Each col As DataColumn In dtDat.Columns 

           Dim obj = drDat(col) 

           If String.Compare(obj.ToString, txtCode.Text, True) = 0 OrElse UseLike And obj.ToString.ToLower.Contains(txtCode.Text.ToLower) Then 

            If Not (From x As Locator In Matches Where x.DB.ToString = drdb!name.ToString And x.Table = dr!name.ToString And x.Column = col.ColumnName).Any Then 
             Dim newOne As New Locator(drdb!name.ToString, dr!name.ToString, col.ToString) 
             Matches.Add(newOne) 
             With newOne 
              ListVresults.Items.Add(New ListViewItem({.DB, .Table, .Column})) 
             End With 

            End If 
           End If 

          Next 
         Next 


        End Using 


       Next 
      End Using 

     Next 
    End Using 

    lblProc.Text = "" 


    Button1.Enabled = True 
End Sub 
0

をやったどのようにそれはあなたのアイデアを与えるかもしれないと。これにより、実行可能な動的な文字列が構築されます。これはすべてのデータベースで機能しませんが、手動で各データベースに対してこれを実行するか、sp_msforeachdbを使用するようにこれを変更することができます。文書化されていないforeachdbが時々データベースを見逃してしまうので、このアプローチがより良いことがわかります。 http://sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/a-more-reliable-and-more-flexible-sp-msforeachdb.aspx

DECLARE @MySearchCriteria VARCHAR(500) 
SET @MySearchCriteria = '''YourSearchStringHere''' --you do need all these quotation marks because this string is injected to another string. 

SELECT 'SELECT ''' + t.name + ''' as TableName, ' + c.columnlist + '] FROM [' + s.name + '].[' + t.name + '] WHERE ' + w.whereclause as SelectStatement 
FROM sys.tables t 
join sys.schemas s on s.schema_id = t.schema_id 
CROSS APPLY (
    SELECT STUFF(( 
     SELECT '], [' + c.Name AS [text()] 
     FROM sys.columns c 
     join sys.types t2 on t2.user_type_id = c.user_type_id 
     WHERE t.object_id = c.object_id 
      AND c.collation_name IS NOT NULL 
      AND c.max_length > 6 
      and t2.name not in ('text', 'ntext') 
     FOR XML PATH('') 
    ), 1, 2, '') 
) c (columnlist) 
CROSS APPLY (
    SELECT STUFF(( 
     SELECT ' OR [' + c.Name + '] IN (' + @MySearchCriteria + ')' AS [text()] 
     FROM sys.columns c 
     join sys.types t2 on t2.user_type_id = c.user_type_id 
     WHERE t.object_id = c.object_id 
      AND c.collation_name IS NOT NULL 
      AND c.max_length > 6 
      and t2.name not in ('text', 'ntext') 
     FOR XML PATH('') 
    ), 1, 4, '') 
) w (whereclause) 
where c.columnlist is not null 
ORDER BY t.name 
0

これは私がいつも使うスクリプトです...トップで検索する文字列を設定します(コメントを参照)、それを実行してみましょう。

DECLARE @tableName sysname 
DECLARE @columnName sysname 
DECLARE @value varchar(100) 
DECLARE @sql varchar(2000) 
DECLARE @sqlPreamble varchar(100) 
DECLARE @minLength int; 

SET @value = '%SomeString%' -- *** Set this to the value you're searching for *** -- 
SET @minLength = LEN(REPLACE(@value, '%', '')); 

SET @sqlPreamble = 'IF EXISTS (SELECT 1 FROM ' 

DECLARE theTableCursor CURSOR FAST_FORWARD FOR 
    SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_SCHEMA = 'dbo' AND TABLE_TYPE = 'BASE TABLE' 
     AND TABLE_NAME != 'dtproperties' AND TABLE_NAME != 'sysdiagrams' 
    ORDER BY TABLE_NAME 

OPEN theTableCursor 
FETCH NEXT FROM theTableCursor INTO @tableName 

WHILE @@FETCH_STATUS = 0 -- spin through Table entries 
BEGIN 
    DECLARE theColumnCursor CURSOR FAST_FORWARD FOR 
     SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 
     WHERE TABLE_NAME = @tableName 
      AND (DATA_TYPE = 'nvarchar' OR DATA_TYPE = 'varchar') 
      AND (CHARACTER_MAXIMUM_LENGTH >= @minlength OR CHARACTER_MAXIMUM_LENGTH = -1) 
     ORDER BY ORDINAL_POSITION 

    OPEN theColumnCursor 
    FETCH NEXT FROM theColumnCursor INTO @columnName 

    WHILE @@FETCH_STATUS = 0 -- spin through Column entries 
    BEGIN 
     SET @sql = N'[' + @tableName + N'] (nolock) WHERE [' + @columnName + N'] LIKE ''' + @value + 
        N''') PRINT ''Value found in Table: ' + @tableName + N', Column: ' + @columnName + N'''' 
     EXEC (@sqlPreamble + @sql) 
     FETCH NEXT FROM theColumnCursor INTO @columnName 
    END 
    CLOSE theColumnCursor 
    DEALLOCATE theColumnCursor 

    FETCH NEXT FROM theTableCursor INTO @tableName 
END 
CLOSE theTableCursor 
DEALLOCATE theTableCursor 
1

編集:

私の答えは、ストアドプロシージャました。 ここにあなたのためのクエリ:

あなたの検索のために@SearchTermを変更してください。

declare @SearchTerm nvarchar(12) 
set @SearchTerm = 'WORD' 
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]; 
関連する問題