martes, 25 de junio de 2013

SQL Server: Últimos accesos a una tabla

Es muy posible que en algún momento hayas pensado en que estaría bien saber cuándo ha sido el

último acceso

a una determinada

tabla

de tu base de datos

SQL Server

, ¿no se os ocurre ningún caso? Imaginemos que hemos modificado cierto código provocando que una

tabla

deje de utilizarse y pueda ser eliminada , ¿estamos seguros que ningún otro código o aplicación acceden a esa

tabla

? A continuación os explicaré cómo podemos saber la

última vez que una tabla ha sido accedida en SQL Server

.

Mediante el uso de la DMV (Dynamic Management View)

sys.dm_db_index_usage_stats

podemos obtener información sobre los

últimos accesos a una tabla en SQL Server

, para ello ejecutaremos la consulta:
-- Lanzamos una consulta sobre la tabla Employee de la BD AdventureWorks
SELECT * FROM HumanResources.Employee

-- Comprobamos los accesos
SELECT tab.name AS Tablename,
       user_seeks, user_scans, user_lookups, user_updates,
       last_user_seek, last_user_scan, last_user_lookup, last_user_update
FROM sys.dm_db_index_usage_stats ius 
INNER JOIN sys.tables tab ON (tab.object_id = ius.object_id)
WHERE database_id = DB_ID(N'AdventureWorks')
  AND tab.name = 'Employee'

Y obtendremos el siguiente resultado:


En cuanto al significado de las distintas columnas del resultado de la consulta:

  • Tablename, nombre de la

    tabla

    por la que estamos filtrando en el WHERE; si no filtramos obtendremos los últimos accesos a todas las tablas de la base de datos.

  • user_seeks, número de consultas de usuario que han utilizado un índice para la búsqueda.

  • user_scans, número de consultas de usuario que han recorrido toda la

    tabla

    .

  • user_lookups, número de consultas de usuario en las que se ha producido un salto del índice a la

    tabla

    para recuperar los datos.

  • user_updates, número de actualizaciones (INSERT / DELETE / UPDATE) que ha realizado un usuario sobre la

    tabla

    .

  • last_user_seek, fecha de la última consulta de usuario que ha utilizado un índice para la búsqueda.

  • last_user_scan, fecha de la última consulta de usuario que ha recorrido toda la

    tabla

    .

  • last_user_lookup, fecha de la última consulta de usuario en la que se ha producido un salto del índice a la tabla para recuperar los datos.

  • last_user_update, fecha de la última actualización (INSERT / DELETE / UPDATE) que ha realizado un usuario sobre la

    tabla

    .

En el ejemplo anterior, al hacer un SELECT sobre la

tabla

Employee se ha sumado 1 en la columna user_scans y se ha actualizado el valor de la columna last_user_scan con la fecha y hora en la que he ejecutado el SELECT. Si queréis más información sobre la DMV

sys.dm_db_index_usage_stats

podéis hacerlo a través de la página correspondiente del MSDN.

Un tema importante a tener en cuenta, los contadores se inicializan a 0 (para las columnas user_xxx) y NULL (para las columnas last_xxx) cada vez que se inicia el servicio

SQL Server

(MSSQLSERVER). Además, cada vez que una base de datos se pone fuera de conexión o se apaga (por ejemplo, porque se establece AUTO_CLOSE en ON), se eliminan todas las filas asociadas a la base de datos. Y hasta aquí el artículo de hoy, espero que os pueda ser útil en algún momento. Recordad también que dentro de

areaTIC

podéis encontrar otros artículos interesantes, no dudéis en consultar nuestro archivo, también podéis seguirnos por RSS o las principales redes sociales (twitter, facebook, linkedin...) 


LECTURAS RELACIONADAS RECOMENDADAS POR AREATIC.NET

martes, 18 de junio de 2013

Windows Phone 8 - Acceso a datos, REST

Esta semana veremos como realizar un enlace a datos desde una aplicación

Windows 8

o

Windows Phone 8

programada en HTML5-javascript llamando a un servicio

REST

.

En primer lugar como base para los servicios

REST

que se llaman desde la app del ejemplo usaremos el site creado hace un tiempo en

areaTIC

que expone una WebAPI con MVC, aquí os dejo el artículo que explica como programarla y configurarla en el IIS local.

Por el resto el ejemplo es muy sencillo, crearemos un nuevo proyecto desde Visual Studio seleccionando la plantilla Javascript - Tienda Windows - Aplicación de diseño fijo. La idea es mostrar una lista de elementos que nos devolverá el servidor al invocar al servicio "Articulo" con el verbo GET.




Si pulsamos F5 sin tocar nada veremos este tipo de plantilla incluye una página fija vacía con el texto "Aquí se debe incluir el contenido".

Vamos a ello, editamos el archivo Html para definir como mostraremos el resultado de la consulta al servidor. En este ejemplo no tocaremos CSS es decir, no aplicaremos estilos ni cuidaremos que nuestro ListView sea "responsive" sino que nos centraremos en el .js para ver como realizar la llamada al servicio

REST

.

HTML:
  • Definimos 2 plantillas (para que la lista de elementos se muestre con estilo metro).
  • Definimos un objeto WinJS.UI.ListView en el punto donde original mente teníamos el párrafo con el texto "Aquí se debe incluir el contenido".
<body>
<!-- Esta plantilla se aplica a los elementos del ListView -->
<div class="itemtemplate" data-win-control="WinJS.Binding.Template">
  <div class="item">
    <img class="item-image" src="#" data-win-bind="src: backgroundImage; alt: title" />
    <div class="item-overlay">
      <h4 class="item-title" data-win-bind="textContent: title"></h4>
      <h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6>
    </div>
  </div>
</div>
         
<div data-win-control="WinJS.UI.ViewBox">
  <div class="fixedlayout">
    <!-- ListView -->
    <div class="groupeditemslist win-selectionstylefilled" data-win-control="WinJS.UI.ListView" data-win-options="{ selectionMode: 'none' }"></div>
  </div>
</div>
</body>
Si ignoramos un poco el CSS que contiene el código HTML y ejecutamos veremos que hasta aquí la aplicación compila, el resultado de momento es una página sin contenido. Para ver como esto avanza lo mejor sería atacar el archivo .js.

Javascript:
  • Definimos una variable para la lista (var lista)
  • Definimos una variable para la página Default.html (var page)
  • En el evento Ready de la página llamaremos al servicio usando WinJS.xhr
  • Vinculamos el resultado de la llamada a la lista y al ListView que hemos creado en la página HTML. Si nos fijamos bien en este punto estamos asociando las plantillas del paso anterior al objeto ListView mediante la propiedad itemTemplate
  • He añadido una imagen areaTIC en la carpeta images del proyecto a la cual hacemos referencia como background en los ítems que se cargarán por pantalla
/ Para obtener una introducción a la plantilla Diseño fijo, consulte la siguiente documentación:
// http://go.microsoft.com/fwlink/?LinkId=232508
(function () {
  "use strict";

  WinJS.Binding.optimizeBindingReferences = true;

  var app = WinJS.Application;
  var activation = Windows.ApplicationModel.Activation;
  var lista = new WinJS.Binding.List();
    

  app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
      if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
       //Esta aplicación se ha iniciado recientemente. Inicializar la aplicación aquí.
       //Definimos variable página Default.html 
       var page = WinJS.UI.Pages.define("default.html", {
                    
         ready: function (element, options) {
         var options = { url: "http://localhost/WebAPI/Api/Articulo" };
         var listView = element.querySelector(".groupeditemslist").winControl;

         listView.itemTemplate = element.querySelector(".itemtemplate");
         
         WinJS.xhr(options).done(
         function completed(request) {
         // Respuesta Servidor
            if (request.status === 200) {
              var articulos = JSON.parse(request.responseText);
              articulos.forEach(function (articulo) {
                var item = { title: articulo.Titulo, 
                             description: articulo.Descripcion, 
                             subtitle: articulo.Autor, 
                             backgroundImage: '../images/areaTic.png' 
                            };
                lista.push(item)
               });
            }

            listView.itemDataSource = lista.dataSource;
            listView.groupDataSource = null;
   
         },

         function error(request) {
         // Si se produce un error en la comunicación con server-
         },

         function progress(request) {
         // permite controlar el progreso
         });

       }
      });
     } else {
       // TODO: Esta aplicación se ha reactivado tras estar suspendida.
       // Restaurar el estado de la aplicación aquí.
     }
     args.setPromise(WinJS.UI.processAll());
    }
    };

    app.oncheckpoint = function (args) {
        // TODO: Esta aplicación está a punto de suspenderse. Guardar cualquier estado
        // que deba mantenerse a través de las suspensiones aquí. Puede usar el
        // objeto WinJS.Application.sessionState, que se guarda y se restaura
        // automáticamente en las suspensiones. Si debe completar una
        // operación asincrónica antes de suspenderse la aplicación, llame a
        // args.setPromise().
    };

    app.start();
})();
Llegado este punto si todo está ok, se debería un intento de grid metro con tantos elementos como ítems devuelva el servicio

REST

al que hemos llamado (en mi caso 2).



Como comentaba al inicio no tocaremos CSS en este artículo, faltaría hacer que la vista sea "responsive" y se adapte a las diferentes modalidades de vista que permite una app

Windows 8

. Os paso un enlace a un articulo de

areaTIC

donde se recomiendan algunos tutoriales entre ellos uno interesante para controlar las vistas en este tipo de aplicaciones.

Espero os haya resultado interesante y como siempre animaros a enviar vuestro feedback y participar vía comentarios y/o redes sociales.

martes, 11 de junio de 2013

Wordpress: Añadir un Sitemap

Con el artículo de hoy iniciamos una serie de artículos en

Wordpress

, el primero, cómo

añadir un sitemap

en tu sitio web. La idea de

añadir un sitemap

es mostrar a los visitantes de nuestro sitio una visión global de su contenido: páginas, entradas,... para ello hay gran cantidad de

plugins

, en este caso es detallaré el uso del

plugin

Table of Contents Creator. Los pasos serían los siguientes:

  1. Entramos en

    Wordpress

    , vamos al apartado

    Plugins

    y pulsamos en la parte superior sobre "Añadir nuevo".


  2. Escribimos el nombre del

    plugin

    , Table of Contents Creator, y pulsamos "Buscar".


  3. Nos aparece en primer lugar de los resultados de búsqueda el

    plugin

    Table of Contents Creator, pulsamos sobre "Instalar ahora".


  4. Una vez acaba la instalación es necesario activar el

    plugin

    pulsando sobre el texto correspondiente.


  5. Una vez activado el

    plugin

    vamos a la lista de

    plugins

    y podemos apreciar que está instalado y activado.


  6. Hasta aquí no hay ningún misterio, seguramente hayáis instalado cientos de

    plugins

    y si no lo habéis hecho y seguís utilizando

    Wordpress

    tranquilos, los instalareis. Bien, vamos a empezar a tratar las particularidades del

    plugin

    , vamos al menú "Ajustes" y vemos que se nos ha añadido la opción Table of Contents Creator, pulsamos sobre ella.


  7. Dentro de los ajustes del

    plugin

    encontramos cinco secciones que podemos ajustar, desplegando cada una de ellas veremos las distintas opciones:

    • Opciones generales donde seleccionaremos apariencia de los iconos, formato fecha, título de la página, textos de ayuda y opciones,...
    • Opciones para el generador de resúmenes donde se hacen ajustes sobre el extracto de las páginas que se mostrará en el

      sitemap

      .
    • Opciones para las páginas estáticas donde indicamos visibilidad, título,...
    • Opciones para las entradas del blog, similar a las páginas pero aplicado a las entradas del blog.
    • Opciones de la sección de comentarios del foro donde se permite dar formato a los comentarios únicamente si se utilizan los

      plugins

      que se especifican.


  8. Una vez tengamos los ajustes pulsamos sobre el botón "Actualizar opciones" para que se guarden y pulsamos sobre el botón "Crear página" para añadir una página con el

    sitemap

    en nuestro sitio. Una vez creada la página, si queremos hacer cambios, simplemente modificaremos las opciones y actualizaremos, no debemos crear la página de nuevo.


  9. Si hemos realizado los pasos anteriores correctamente obtendremos un resultado similar a éste. Es cuestión de ir jugando con los ajustes del

    plugin

    Table of Contents Creator para conseguir el aspecto deseado.


Y hasta aquí el artículo de hoy de cómo añadir un

sitemap

en un sitio realizado con

Wordpress

, seguro que conocéis otros

plugins

que nos permitan hacerlo, si lo creéis oportuno podéis compartirlo con todos nuestros lectores. Recordad también que dentro de

areaTIC

podéis encontrar otros artículos, no dudéis en consultar nuestro archivo, también podéis seguirnos por RSS o las principales redes sociales (twitter, facebook, linkedin...) 


martes, 4 de junio de 2013

Cliente REST en VBA

A raíz de unas utilidades que hemos de desarrollar en nuestros verticales surgió la necesidad de crear clientes

REST

desde aplicaciones que usan lenguajes

VBA

(asp, Visual Basic 6.0, Macros de Excel, vbs)… Trabajando en estos entornos no encontraremos una dll oficial que nos sirva para conectar a un servicio

REST

lo cual tiene bastante sentido porque

VBA

dejó de ampliarse ya hace 10 años con el paso a .NET y

REST

es un tema emergente que se ha puesto de moda estos últimos años.

Aún así teniendo en cuenta que

REST

no es más que una petición

HTTP

, usando la librería msxml.dll que aún podemos descargar en la página de Microsoft se podría crear un cliente

REST

sin problemas en este tipo de aplicaciones.

Con esta dll ya podremos realizar llamadas

HTTP

controlando el verbo y las cabeceras de la petición, pero no incorpora utilidades para convertir cadenas

JSON

a objetos ni viceversa. Tirando de google un poco veo que hay gente que opta por usar las dll que .NET sí que mantiene donde es bastante sencillo realizar este tipo de acciones con parseJSON y métodos del estilo, para ello generan una dll desde .NET que vinculan desde las aplicaciones

VBA

usando interops o convirtiendo la dll .NET en objeto COM. En nuestro caso dada la naturaleza del parque de aplicaciones que mantengo actualmente y teniendo en cuanto como se despliegan las aplicaciones a los usuarios era una solución un poco engorrosa. Hemos optado por descargar esta solución Visual Basic 6.0 y aprovechar las utilidades

JSON

en nuestras aplicaciones.

Una vez tenemos estos 2 requisitos veamos como implementar un GET de ejemplo y a partir de ahí cada uno podría montarse su clase proxy genérica para trabajar contra distintos servicios que sigan el patrón

REST

desde aplicaciones VBA. El GET haremos que ataque al servicio

REST

(artículo) que creamos hace unas semanas en

areaTIC

y debería devolvernos la misma información que si usamos el cliente genérico .NET que creamos también hace unas semanas en

areaTIC

.
Option Explicit

Private m_url as string 
Private m_Service as string 

Public Function GetFromWebAPI(ByVal strValue As String) As ADODB.Recordset
    Dim oHttReq As MSXML2.XMLHTTP
    On Error GoTo errorFunction
           
   'Definimos URL y Servicio, en este caso es específico la URL se corresponde con el proyecto Web MVC API que tengo en mi IIS local. 
   m_url  = "http://localhost/WebApi/Api"
   m_Service = strValue

    ' Enviar el comando al servicio Web
    ' usar XMLHTTPRequest para enviar la información al servicio Web
    Set oHttReq = New XMLHTTP

    ' Enviar el comando de forma síncrona 
    oHttReq.open "GET", m_url & "/" & m_Service, False

    ' las cabeceras a enviar en la petición HTTP
    ' oHttReq.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
    
   ' enviar el comando
    Dim body As String
    oHttReq.send
    body = oHttReq.responseText
    
    Dim oRstDatos As ADODB.Recordset
    Set oRstDatos = ParseJSON(body)
    
    Set oHttReq = Nothing
    Exit Function
errorFunction:
    Err.Raise Err.Number
End Function
Option Explicit

Private Sub Command1_Click()
    Dim rest_client As New RESTClient
    Dim rs As ADODB.Recordset
    Set rs = rest_client.GetFromWebAPI("articulo")
    
    rs.MoveFirst
    MsgBox rs.GetString
End Sub

Comentar que hemos usado como base para el método parseJSON el código fuente descargado del enlace que os presentaba al principio del artículo pero hemos añadido un método para convertir el diccionario de valores en un Recordset dinámico ya que dada la naturaleza de nuestras aplicaciones

VBA

nos resultaba muy útil. No hay problema en subir el código de ejemplo si alguien está interesado hacérnoslo saber que os paso el proyecto de test que he usado para realizar el cliente

REST VBA

. Como siempre espero que el artículo os resulte interesante, cualquier duda o valoración hacerla llegar a través de comentarios, emails o como buenamente os apetezca. Recuerda que puedes seguir

areaTIC

en las redes sociales, anímate a participar!