简体   繁体   English

在所有数据库 - 表 - 列文本中搜索字符串

[英]Search through all Database - Tables - Column Text for a string

Issue问题


We are in the process of changing a database name on our server, but the database is huge and we want to create a small application that will loop through all databases, and then all the tables in the databases and then all the columns in the tables for text that matches "LIVE".我们正在更改服务器上的数据库名称,但是数据库很大,我们想创建一个小应用程序,它将遍历所有数据库,然后遍历数据库中的所有表,然后遍历表中的所有列对于匹配“LIVE”的文本。

Code代码


I started creating code but i feel like this way in clunky and is returning an error.我开始创建代码,但我觉得这种方式笨拙并且返回错误。

        using (SqlConnection connection = new SqlConnection(@"data source="SERVER NAME";integrated security=false;uid="USER";password="PASSWORD";"))
        {
            connection.Open();

            SqlCommand command = new SqlCommand(@"SELECT * FROM sys.databases", connection);


            SqlDataReader reader = command.ExecuteReader();

            try
            {
                while (reader.Read())
                {
                    _databases.Add(string.Format("{0}", reader["name"]));
                }
            }
            finally
            {
                reader.Close();
            }

            foreach (var database in _databases)
            {
                using (SqlConnection tableconnection = new SqlConnection(string.Format(@"data source="SERVER NAME";initial catalog=" + database + ";integrated security=false;uid="USERNAME";password="PASSWORD";")))
                {
                    tableconnection.Open();

                    SqlCommand tablecommand = new SqlCommand(@"SELECT * FROM information_schema.tables", tableconnection);

                    SqlDataReader readertable = tablecommand.ExecuteReader();

                    try
                    {
                        while (readertable.Read())
                        {
                            _tables.Add(string.Format("{0}", readertable["TABLE_NAME"]));
                        }
                    }
                    finally
                    {
                        readertable.Close();
                    }

                    foreach (var tables in _tables)
                    {

                        SqlCommand columncommand = new SqlCommand(string.Format(@"SELECT * FROM INFORMATION_SCHEMA.COLUMNS where TABLE_Name=" + tables, tableconnection));

                        SqlDataReader readercolumn = columncommand.ExecuteReader();

                        try
                        {
                            while (readercolumn.Read())
                            {
                                _columns.Add(string.Format("{0}", readercolumn["COLUMN_NAME"]));
                            }
                        }
                        finally
                        {
                            readercolumn.Close();
                        }
                    }


                }


            }
        }

As you can see I am unsure if this is the best way to do it.如您所见,我不确定这是否是最好的方法。 The code errors on:代码错误:

SqlDataReader readercolumn = columncommand.ExecuteReader();

and the error is:错误是:

Additional information: ExecuteReader: Connection property has not been initialized.

Does anyone know what is going wrong or a simple way to do this?有谁知道出了什么问题或一个简单的方法来做到这一点?

You can use this for your problem :).你可以用它来解决你的问题:)。 :

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

And use it like this :并像这样使用它:

exec SearchAllDatabases @SearchTerm = '%value%'

Or execute this stored procedure from your code.或者从您的代码执行此存储过程。

using (SqlConnection connection = new SqlConnection(@"data source="SERVER NAME";integrated security=false;uid="USER";password="PASSWORD";"))
{
conn.Open();

// 1.  create a command object identifying the stored procedure
SqlCommand cmd  = new SqlCommand("SearchAllDatabases", conn);

// 2. set the command object so it knows to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;

// 3. add parameter to command, which will be passed to the stored procedure
cmd.Parameters.Add(new SqlParameter("@SearchTerm", value));

cmd.ExecuteNonQuery();  
}

Your code你的代码

SqlCommand columncommand = new SqlCommand(string.Format(@"SELECT * FROM INFORMATION_SCHEMA.COLUMNS where TABLE_Name=" + tables, tableconnection));

The end of the statement has )), putting table connection as a parameter for string.Format, which you dont use, so either, move it or...语句的结尾有 )),将表连接作为 string.Format 的参数,您不使用它,因此要么移动它,要么...

You should have:你应该有:

 SqlCommand columncommand = new SqlCommand(@"SELECT * FROM INFORMATION_SCHEMA.COLUMNS where TABLE_Name=" + tables, tableconnection);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM