miércoles, 15 de diciembre de 2010

Analizar automáticamente los resultados de SSUA

Uno de los principales procesos a seguir cuando se planea la migración de SQL Server hacia una versión superior del motor es la de analizar los potenciales problemas de incompatibilidad entre versiones.

Actualmente, se viene percibiendo en el mercado una gran cantidad de proyectos de migración desde versiones de SQL Server 2000 hacia SQL Server 2008 y 2008 R2. Dichos proyectos, principalmente vienen motivados tanto por la gran cantidad de mejoras y características que vienen de serie con las últimas versiones del motor, como de la necesidad de actualización debida a la pérdida de soporte de SQL Server 2000 por parte de Microsoft (http://support.microsoft.com/lifecycle/?p1=2852)

Debido a esta circunstancia, no solo el número de proyectos de migración se incrementa, sino que el número de instancias y bases de datos a migrar se multiplica (por experiencia encuentro que típicamente se tienen más de 3 instancias de SQL Server, con 10 BBDD cada una de media). Debido a esta circunstancia, al realizar assesments de migración hacia SQL Server 2008 y 2008 R2, debemos manejar mucha información.

En Solid Quality Mentors, hemos desarrollado una herramienta que hemos denominado HealthCheck y sobre la que hablaremos desde esta revista asiduamente, con la que entre otras cosas, facilitamos el trabajo con los ficheros de resultados de SSUA.

¿Qué es SSUA (Sql Server Upgrade Advisor)?

Es una herramienta gratuita proporcionada por Microsoft, para realizar labores de detección de patrones T-SQL y configuraciones depreciadas de SQL Server. Con ella, podremos saber si en cualquier objeto de nuestra base de datos existe una construcción sintáctica T-SQL depreciada que no funcionará en la versión del motor a la que deseamos migrar.

¿Por qué deseamos una automatización de los resultados de SSUA?

Como he avanzado al principio del artículo, una migración típica involucra más de una instancia de SQL Server, es por ello que en ocasiones analizar los resultados puede resultar una tarea tediosa.

¿Qué pretendemos automatizar?

La idea, es generar un fichero que contenga una línea por objeto a modificar, con información extra que con nuestra propia experiencia en la materia nos ayude a identificar lo que es costoso de lo que no, para que de un vistazo rápido, podamos realizar una valoración objetiva lo más acercada a la realidad, de lo que el coste del proyecto final nos puede suponer.

En la imagen siguiente, se puede apreciar como la forma de presentar los resultados por parte de SSUA aunque acertada, no es todo lo útil que desearíamos cuando tenemos que lidiar con múltiples objetos y/o ficheros de resultado.

clip_image002

No obstante, SSUA nos ofrece la posibilidad de exportar la información a un fichero .csv

clip_image004

Cuyo resultado es como el siguiente (después de procesarlo introduciendo sus valores en celdas):

clip_image006

La parte buena es que como se puede apreciar, aparece información de forma tabular. La parte no tan buena es que sigue sin ser completamente controlada por nosotros (“Database name: master”, por ejemplo no es óptimo porque sobraría “Database name:”).

La idea por tanto es que de una manera fácil y sencilla, haciendo uso de las características inherentes de Visual Studio y .net 4.0, podamos operar con los XML resultado de una forma exitosa y fácil.

Procesamiento del documento XML

La idea que me gustaría ilustrar, es que podemos procesar los resultados de SSUA de una forma cómoda y rápida usando Visual Studio 2010. Para ello, una vez obtenida la información con SSUA (resultados típicamente obtenidos bajo la ruta “\Documents\SQL Server 2008 Upgrade Advisor Reports”), procedemos a crearnos un esquema .xsd del documento XML con los resultados deseados ( DE.xml por ejemplo, es el que contendrá los resultados del motor relacional).

Abrimos el documento desde Visual Studio 2010 y seguidamente nos vamos a las opciones de menú XML->Create Schema

clip_image007

Una vez pulsado ahí, obtendremos su esquema .xsd

clip_image009

Como vemos, nada nuevo. La gracia viene ahora.

Podemos crearnos un proyecto de Visual Studio, al que añadir el siguiente código:

Code Snippet
  1.         public static DataTable Analyze(string pathToXml)
  2.         {
  3.             FillIssueTimming();
  4.             DataSet ds = new DataSet();
  5.             ds.ReadXmlSchema("SSUA\\XMLSchemas\\DE.xsd");
  6.             ds.EnforceConstraints = false;
  7.             XmlDataDocument xml = new XmlDataDocument(ds);
  8.             xml.Load(pathToXml);
  9.             var query = from ia in ds.Tables["ItemAttribute"].AsEnumerable()
  10.                         join ias in ds.Tables["ItemAttributes"].AsEnumerable()
  11.                             on ia.Field<int>("ItemAttributes_id") equals ias.Field<int>("ItemAttributes_id")
  12.                         join item in ds.Tables["Item"].AsEnumerable()
  13.                              on ias.Field<int>("Item_id") equals item.Field<int>("Item_id")
  14.                         join r in ds.Tables["Report"].AsEnumerable()
  15.                             on item.Field<Nullable<byte>>("ItemId") equals r.Field<Nullable<byte>>("ItemId")
  16.                         join iss in ds.Tables["Issue"].AsEnumerable()
  17.                             on r.Field<Nullable<byte>>("IssueId") equals iss.Field<Nullable<byte>>("IssueId")
  18.                         select new
  19.                         {
  20.                             ItemAttributesId = ia.Field<int>("ItemAttributes_id"),
  21.                             Name = ia.Field<string>("Name"),
  22.                             Value = ia.Field<string>("Value"),
  23.                             Issue = iss.Field<string>("IssueDescription"),
  24.                             IssueText = iss.Field<string>("IssueText"),
  25.                             IssueType = iss.Field<string>("IssueType")
  26.                         };
  27.  
  28.           // Get all the info you want in the export file
  29.           //
  30. DataTable resultado = new DataTable("results");
  31.             resultado.Columns.Add("IssueId", typeof(int));
  32.             resultado.Columns.Add("IssueType", typeof(string));
  33.             resultado.Columns.Add("Source Type", typeof(string));
  34.             resultado.Columns.Add("Database Name", typeof(String));
  35.             resultado.Columns.Add("Object Name", typeof(String));
  36.             resultado.Columns.Add("Object Type", typeof(String));            
  37.             resultado.Columns.Add("Keyword", typeof(String));
  38.             resultado.Columns.Add("Issue", typeof(String));
  39.             resultado.Columns.Add("SQL Batch", typeof(string));
  40.             resultado.Columns.Add("Trace File", typeof(string));
  41.             resultado.Columns.Add("IssueText", typeof(String));
  42.             resultado.Columns.Add("Estimated time of adaptation", typeof(String));
  43.             resultado.Columns.Add("Comments", typeof(String));
  44.  
  45.    foreach(var row in query)
  46.             {
  47.                 if (issueid_old != row.ItemAttributesId)
  48.                 {
  49.                     DataRow dr = resultado.NewRow();
  50.                     dr["IssueId"] = row.ItemAttributesId;
  51.                     dr["IssueType"] = row.issuetype;
  52.                     dr["Database Name"] = row.Value;
  53.                     dr["Issue"] = row.issue;
  54.                     dr["IssueText"] = row.issuetext;
  55.                                                  …
  56.                  }
  57.              }
  58.              …
  59.             return(resultado);
  60. }

Con esa sencilla consulta (a la que por supuesto podemos añadir todas las columnas que queramos), podemos obtener un DataTable que facilmente podemos exportar al formato que queramos (separado por comas o directamente a Excel usando la API OpenXML o Excel Interop).

Ahora tenemos la información procesada por nosotros, y en tan solo 5-10 minutos podremos tener nuestro exportador de datos de SSUA, al que por ejemplo le añadamos información extra relativa a tiempos estimados de análisis o migración basándonos en nuestra experiencia (como por ejemplo ocurre en nuestro HealthCheck).

Publicar un comentario