例としてMS SQL ServerとC#.NETを使用して、指定されたすべてのサーバーのすべてのデータベースに要求を送信する

まえがき



多くの場合、すべてのデータベース(データベース)に指定されたすべてのサーバーに要求を送信する必要があります。 組み込みツールを使用して、多くのDMLクエリを作成できます。 たとえば、そのような 。 しかし、DDLクエリはどうでしょうか?



この記事では、MS SQL ServerとC#.NETを使用して、指定されたすべてのサーバーのすべてのデータベースに要求を送信するアプリケーションの実装例を分析します。



解決策



たとえば、ビューを作成または変更する必要があります(たとえば、 タスクからビューを作成する )。



リクエスト
USE [__] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE view [inf].[vTableSize] as with pagesizeKB as ( SELECT low / 1024 as PageSizeKB FROM master.dbo.spt_values WHERE number = 1 AND type = 'E' ) ,f_size as ( select p.[object_id], sum([total_pages]) as TotalPageSize, sum([used_pages]) as UsedPageSize, sum([data_pages]) as DataPageSize from sys.partitions p join sys.allocation_units a on p.partition_id = a.container_id left join sys.internal_tables it on p.object_id = it.object_id WHERE OBJECTPROPERTY(p.[object_id], N'IsUserTable') = 1 group by p.[object_id] ) ,tbl as ( SELECT t.[schema_id], t.[object_id], i1.rowcnt as CountRows, (COALESCE(SUM(i1.reserved), 0) + COALESCE(SUM(i2.reserved), 0)) * (select top(1) PageSizeKB from pagesizeKB) as ReservedKB, (COALESCE(SUM(i1.dpages), 0) + COALESCE(SUM(i2.used), 0)) * (select top(1) PageSizeKB from pagesizeKB) as DataKB, ((COALESCE(SUM(i1.used), 0) + COALESCE(SUM(i2.used), 0)) - (COALESCE(SUM(i1.dpages), 0) + COALESCE(SUM(i2.used), 0))) * (select top(1) PageSizeKB from pagesizeKB) as IndexSizeKB, ((COALESCE(SUM(i1.reserved), 0) + COALESCE(SUM(i2.reserved), 0)) - (COALESCE(SUM(i1.used), 0) + COALESCE(SUM(i2.used), 0))) * (select top(1) PageSizeKB from pagesizeKB) as UnusedKB FROM sys.tables as t LEFT OUTER JOIN sysindexes as i1 ON i1.id = t.[object_id] AND i1.indid < 2 LEFT OUTER JOIN sysindexes as i2 ON i2.id = t.[object_id] AND i2.indid = 255 WHERE OBJECTPROPERTY(t.[object_id], N'IsUserTable') = 1 OR (OBJECTPROPERTY(t.[object_id], N'IsView') = 1 AND OBJECTPROPERTY(t.[object_id], N'IsIndexed') = 1) GROUP BY t.[schema_id], t.[object_id], i1.rowcnt ) SELECT @@Servername AS Server, DB_NAME() AS DBName, SCHEMA_NAME(t.[schema_id]) as SchemaName, OBJECT_NAME(t.[object_id]) as TableName, t.CountRows, t.ReservedKB, t.DataKB, t.IndexSizeKB, t.UnusedKB, f.TotalPageSize*(select top(1) PageSizeKB from pagesizeKB) as TotalPageSizeKB, f.UsedPageSize*(select top(1) PageSizeKB from pagesizeKB) as UsedPageSizeKB, f.DataPageSize*(select top(1) PageSizeKB from pagesizeKB) as DataPageSizeKB FROM f_size as f inner join tbl as t on t.[object_id]=f.[object_id] GO
      
      







このビューには、各データベース(データベース)のすべてのテーブルのサイズが表示されます。



FileQuery.sqlファイルを作成し、そこに上記のクエリを記述します。 ここで、ファイルからすべてのデータベースに、指定されたすべてのサーバーにリクエストを送信する関数を定義します。



機能
 /// <summary> ///        /// </summary> /// <param name="server">   ( MS SQL Server)</param> /// <param name="sql">T-SQL-</param> /// <param name="tw_log">  </param> void RunQueryInAllDBServer(string server, string sql, TextWriter tw_log) { SqlConnectionStringBuilder scsb = null; //       List<string> ldbs = new List<string>(); //   scsb = new SqlConnectionStringBuilder(); scsb.ApplicationName = "_"; scsb.InitialCatalog = "master"; scsb.IntegratedSecurity = true; scsb.DataSource = server; //         MS SQL Server tw_log.WriteLine($"{DateTime.Now} ServerName: {server}:"); //           using (SqlConnection conn = new SqlConnection()) { conn.ConnectionString = scsb.ConnectionString; SqlCommand comm = new SqlCommand("select [name] from sys.databases"); comm.CommandType = System.Data.CommandType.Text; comm.Connection = conn; conn.Open(); var result = comm.ExecuteReader(); while (result.Read()) { ldbs.Add(result.GetString(0).ToString()); } } //  sql     for (int i = 0; i < ldbs.Count; i++) { using (SqlConnection conn = new SqlConnection()) { scsb.InitialCatalog = ldbs[i]; conn.ConnectionString = scsb.ConnectionString; SqlCommand comm = new SqlCommand(sql); comm.CommandType = System.Data.CommandType.Text; comm.Connection = conn; conn.Open(); try { comm.ExecuteNonQuery(); tw_log.WriteLine($"{DateTime.Now} DBName: {ldbs[i]}   "); } catch(Exception exp) { tw_log.WriteLine($"{DateTime.Now} DBName: {ldbs[i]} Exception: {exp.Message}"); } } } }
      
      







この関数は、MS SQL Serverのインスタンスの名前、T-SQLクエリ、およびログのストリームを取得します。 内部には、すべてのサーバーデータベースの名前のリストが表示されます。 次に、各データベースに対して要求が行われます。 セキュリティ上の理由から、Windows認証は次のように設定されています:scsb.IntegratedSecurity = true;



また、この関数はすべてのサーバーデータベースで要求を実行するため、注意が必要です。



次に、上記の関数の呼び出しコードを作成します。



コード
 string sql = null; using (Stream st_log = new FileStream("___", FileMode.Create, FileAccess.Write)) { using (TextWriter tw_log = new StreamWriter(st_log, Encoding.Default)) { using (Stream st = new FileStream("FileQuery.sql", FileMode.Open, FileAccess.Read)) { using (TextReader tr = new StreamReader(st, Encoding.Default)) { sql = tr.ReadToEnd(); } } // servers-   MS SQL Server,      T-SQL for (int i = 0; i < servers.Length; i++) { RunQueryInAllDBServer(servers[i], sql, tw_log); } tw_log.WriteLine($" {DateTime.Now}"); } }
      
      







それだけです アプリケーションの準備ができました。 当然、サーバーのリストと要求ファイルへのパスは、設定に配置するのが最適です。



結果



この記事では、ファイルに書き込まれた要求を、指定されたすべてのサーバーのすべてのデータベースに送信する例を検討しました。 これにより、DDLクエリをすべてのデータベースに送信できますが、sp_MSForEachDBのドキュメント化されていないストアドプロシージャでは実行できません。



このタスクまたは同様のタスクに使用するツールは何ですか?



ソース:



» MSDN

» すべてのMS SQL Serverデータベースのテーブルおよびファイルの成長に関するデータを収集する自動化

» すべてのテーブルまたはすべてのデータベースに一度に操作を適用する方法



All Articles