lunes, 29 de diciembre de 2014

Filtrar datos de un DataGridView VB 2008

 
 
#Filtrar #DataGridView #VB .
 
 
Revisando por ahí encontré este pequeño tutorial que hice hace ya varios años y quiero compartirlo con Uds., espero aún sea de interés de alguien y dando comienzo a una nueva etapa con el blog, en el cual no haré tantos videos, por problemas de tiempo, trataré de aportar tutoriales escritos, claro está, debo reconocer, que hacer los videos me gusta mucho más.
 
Principalmente, lo que se hará es lo siguiente, tener un formulario en Visual Basic 2008 que contenga un DataGridView, el cual muestra los datos devueltos por un SP, pero el trabajo principal no es mostrar eso, sino que una vez cargado el datagridview, que desde un TextBox, se pueda digitar algunos caracteres y aplicarle un filtro a dicha información. Y que quede como muestro a continuación 
 
 
Como mencioné, no es la finalidad utilizar el SP, así que eso lo dejaré para otro momento (cuando ya haga un Video Tutorial), de momento arrancamos con el DataGridView cargado de datos. 

Requisitos: 
- Formulario (Cualquier nombre) 
- DataGridView (GrdUser) 
- TextBox (txtEM) 
 
 
En el formulario, vamos a declarar una variables (Datos) de tipo DataView 

programación 

Para inicializar el DataGridView, lo haremos de la siguiente forma: 

tutorial 

Y ya casi lo tenemos listo, sólo nos falta, ir al evento KeyPress (es el que yo escogí) y ahí ponemos el código para que se actualice nuestro DataGridView 

Daniel03

Y listo, trabajamos el DataGridView con un DataView para filtrar utilizando la propiedad RowFilter y aplicándole el filtro al estilo LIKE. 

martes, 25 de noviembre de 2014

3 Introducción a Firefox OS - Nuestra Primer Aplicación

#Video 3.1 #Curso #FirefoxOS #TEF_FirefoxOS.

Continuando con el curso, en esta ocasión les traigo la tercera parte, la cual como resultó de 23 minutos, lo que hice fue dividirla en 4 partes, para que uds. tengan una mejor comprensión y comodidad.



3.1  Presentación de la Aplicación.



3.2  Archivos de la Aplicación.



3.3  Herramientas de Desarrollo de Firefox.



3.4  Aplicación en el Simulador.




Para los que tengan más tiempo o quieren ver de una sola vez todo, les dejo el video completo.



Espero pronto ya tener la cuarta entrega de este curso.

Para descargar la aplicación empaquetada, comparte el link en twitter o facebook.


Y recuerden que:

miércoles, 19 de noviembre de 2014

2. Introducción a Firefox OS - Conceptos y Teoría


#Video #2 #Curso Introducción a #FirefoxOS .


Luego de algún tiempo de inactividad, retomo el curso de Firefox OS, en este video veremos la parte teórica, principalmente los conceptos básicos que debemos manejar para poder desarrollar una aplicación para Firefox Os.



Debo aclarar, que la parte de HTML5, CSS y JavaScript lo veremos en el otro curso sobre esta temática.

Sin más, les dejo el video.



Y recuerden:

Enseñando es la mejor forma de aprender


jueves, 30 de octubre de 2014

Todos las redes sociales en un mismo lugar


#Social #Media #DEBSConsultores @DEBSConsultores .

Es este pequeño post, he querido informarles que ya pueden encontrar toda la información de DEBS Consultores, desde un único sitio, el cual es la fan page de Facebook, desde ahí tendrán acceso a por lo menos las tres redes sociales donde más he publicado (El Blog, YouTube y Twitter).

Como pueden ver en la siguiente imagen adjunta, he agregado tres pestañas más al Fan Page de DEBS Consultores para que de esta forma no tengas que estar entrando y saliendo en una u otra red social.


Bueno, espero que te sea agradable esta actualización y muy pronto, espero tener lista una aplicación para Facebook.  De momento, con esta opción podrás vigilar estos tres lugares sin salir de Facebook y así no te perderás de ninguno de los cursos que he preparado.

Y recuerden que Enseñando es la mejor forma de aprender.

miércoles, 29 de octubre de 2014

1. Introducción a Firefox OS - Presentación


#FirefoxOS #Curso #Video #Gratis #Free #Html5 #JavaScript #CSS3

Hola a tod@s.  Iniciamos con el curso de Introducción a Firefox OS, en esta ocasión, hacemos una breve reseña de qué es este nuevo sistema operativo y algunos editores que podemos usar.

Debo resaltar, que para tener una mejor comprensión de los siguientes videos, debes de tener una base de conocimiento de HTML5, JavaScript y CSS3.

Sin más les dejo el Video:


Y recuerden:

Enseñando es la mejor forma de aprender

lunes, 27 de octubre de 2014

Curso introductorio Firefox OS


#Preparando #Nuevo #Curso #Introducción #FirefoxOS

Hola a tod@s, luego de un tiempo de no publicar nada, por motivos de trabajo, vamos a volver muy pronto con este curso, ¿Qué les parece? Opinen por favor. 



Luego de este curso, iniciaremos uno de #HTML5 #CSS3 y #JavaScript orientado al desarrollo para Firefox OS, lo más óptimo hubiese sido iniciar con este curso, pero el de Firefox es más rápido, posiblemente lo saquemos en dos o tres videos, máximo cuatro.

Bueno, esto es lo que viene pronto, espero les guste y comenten, les dejo una pequeña presentación en video.

lunes, 8 de septiembre de 2014

Uso de Skin de DevExpress


#Uso #Skin #DevExpress #DEBSConsultores

En esta ocasión voy a iniciar con el pimer mini video tutorial, que consiste en un pequeño video (de no más de 10 minutos), en el cual explicaré algo de forma rápida y concisa.

Hoy le tocó el turno a los skin del DevExpress, veremos cómo es sencillo (con 4 instrucciones) mostrarlos.







Y recuerda que

"Enseñando es la mejor forma de aprender"


miércoles, 30 de julio de 2014

Poblar GridControl DevExpress con DEBSAccesoDatos.dll



Poblar #GridControl de #DevExpress con #DEBSAccesoDatos #Free #DLL.

Hola en esta ocasión les dejo un pequeño tutorial de cómo poblar un GridControl de DevExpress utilizando la librería gratuita DEBSAccesoDatos.dll.

Es bastante sencillo, esta librería agiliza mucho el proceso de desarrollo de software.




"Enseñar es la mejor forma de aprender"


miércoles, 16 de julio de 2014

Posible curso Bootstrap 3


#BootStrap #BootStrap3 #Pronto #WebResponsive via @DEBSConsultores

En esta ocasión les traigo algo que quiero preparar para algún futuro curso, no es ni más ni menos que algo sobre Bootstrap, he estado leyendo y les dejo unas pequeñas pruebas que estoy haciendo.



Siempre tratando de hacer sencillo, les dejo este pequeño video donde muestro (bastante rápido) lo que hice, lo más importante es ver la parte de Web Response (o lo que pude poner de momento).
Si tiene buena recepción, claro que lo tendré en cuenta para preparar un curso por lo que es importante que lo compartan (o comenten), qué les parecería un curso de este tópico.



"Enseñar es la mejor forma de aprender"


martes, 17 de junio de 2014

Índice de Artículos



En este artículos, les dejo un pequeño script para poner un índice dinámico en tu blog.


Loading...
Mil Trucos Blogger

Si querés tener este vistoso índice, te invito a que vayás al blog de sus creadores haciendo click aquí.

miércoles, 11 de junio de 2014

Fundamentos Web - Algo de historia



#Web #PHP #MySQL #Fundamentos

Recorriendo la web en busca de documentación, me encontré en varios sitios este documento (ellos lo llaman libro o Ebook), que elaboré más o menos para 2007 ó 2008.  Me dio algo de nostalgia, así que decidí bajarlo para recordar todo lo que hice en esa época y como es costumbre, lo comparto con Uds.

Este material lo elaboré para cuando iniciaba como catedrático en una universidad de por estos lados, para serles honesto, fue la primer clase que impartí, para lo cual hice esta recopilación (y aportaciones mías), no tengo la menor idea de cómo llegó a internet, puede que yo mismo, en mi afán de compartir conocimiento lo subiera a algún servidor.

 
Si alguien desea bajarlo, para referencia, para recuerdo o lo que sea, les dejo el link, sólo deben de darle Click en el botón que dice "Pay with a Tweet".
 


"Enseñar es la mejor forma de aprender"


domingo, 8 de junio de 2014

Gif Animado Photoshop CC


#Gif #Animado #Photoshop #PhotoshopCC

En esta ocasión, les dejo una "segunda parte", del video Gif Animado, la salida que buscamos es la siguiente:


Sin más, les dejo el video:



Ver el perfil de Daniel Bojorge en LinkedIn 

lunes, 2 de junio de 2014

Agregar Borde con Marco a foto con Photoshop


#Photoshop #Video #Tutorial 

Nuevo video de uso de Photoshop, en este caso, tomamos una imagen y creamos bordes con marco, el resultado es algo así:



 

Sin más, te dejo el video

viernes, 30 de mayo de 2014

ABC con jQuery, Ajax, PHP

#CRUD #ABC #jQuery #Ajax #PHP

En esta ocasión, les dejo un artículo dedicado a construir un completo ABC (Altas, Bajas y Cambios) o CRUD, sobre una tabla MySQL, mediante el uso de las herramientas:

  • PHP
  • jQuery
  • Ajax

Tratamos de hacer todo, desde cero, esto que indica, que no trabajamos con ningún plugin de jQuery, sino que todo lo hicimos a mano. ¿Porqué hacerlo así? En algunas ocasiones, tenemos un buen plugin de jQuery que hace algo, pero queremos además agregarle una funcionalidad extra, por ejemplo, tenemos un plugin que valida un formulario, pero queremos que haga el envío de los datos mediante ajax y de esa forma, actualice la tabla en MySQL (ya sea para borrar, actualizar o agregar un registro), pero sin recargar el sitio en el que estamos.

Para tal motivo, iniciamos con este artículo, tratamos de dejarlo lo más completo posible, además agregamos funcionalidades tales como refrescar la información y dar clic a una tabla y abrir la "ventana" de actualización.

Por todo lo anteriormente mencionado, creamos este Tutorial dedicado a los que están comenzando o quieren ver nuevas opciones con jQuery.

 
 

Aclaración

 
Antes de iniciar, vamos hacer algunas aclaraciones:

  • Las acciones de agregar/actualizar,consultar y borrar, se harán desde archivos separados, para esto creamos cada archivo según la necesidad, en el caso de Agregar/Actualizar, en un único archivo se procesan las dos acciones.
  • La tabla donde se muestran los registros se cargará dinámicamente, por lo tanto se debe crear el archivo de consulta (llamado getdata.php).
  • El archivo modificar.php, muestra el formulario desde donde se llama las acciones de actualizar/agregar y borrar.
  • El archivo conex.php contiene las instrucciones de conexión a la base de datos, se debe adecuar al hosting donde se vaya a ejecutar.
 

Desarrollo

Estructura de la tabla utilizada


CREATE TABLE `tmp_usuarios` (
  `user` varchar(20) NOT NULL,
  `pass` varchar(20) NOT NULL,
  `correo` text NOT NULL,
  `estado` tinyint(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8

Contenido de Archivos PHP

getdata.php


<?php
/*Contenido del archivo getdata.php
el cual construye la tabla en html que mostrará los datos de los usuarios
a partir de la tabla tmp_usuarios
*/
include('conex.php');
 
$sql = "Select * from tmp_usuarios" ;
$resUser = mysql_query($sql, $conex) or die(mysql_error());
$totUser = mysql_num_rows($resUser);
 
if ($totUser> 0) {
 
$tabla  = '<table width="100%" border="1" id="tblUser">';
$tabla .= '<tr>';
$tabla .= '   <th scope="col">Usuario</th>';
$tabla .= '   <th scope="col">Clave</th>';
$tabla .= '   <th scope="col">Correo</th>';
$tabla .= '  </tr>';
 
   while ($rowUser = mysql_fetch_assoc($resUser)) {
    $tabla .= '  <tr>';
    $tabla .= '    <td>' . $rowUser["user"]. '</td>';
    $tabla .= '    <td>' . $rowUser["pass"]. '</td>';
    $tabla .= '    <td>' . $rowUser["correo"]. '</td>';
    $tabla .= '   </tr>';
   }
   $tabla .= ' </table>';   
   echo $tabla;
}else{
    echo "NO hay Información que mostrar";
    }
 
?>

deluser.php


<?php
/*Contenido archivo deluser.php*/
include('conex.php');
 
$user  = $_POST["nombre"];
 
if(empty($user)) {
    echo "0";
    return false;
}
$sql = "Delete from tmp_usuarios where user='" . $user ."'" ;
 
mysql_query($sql, $conex) or die(mysql_error());
echo "1";
?>

saveuser.php


<?php
/*
Contenido del archivo saveuser.php
Se procesa el actualizar (update) y el Insertar (Insert)
*/
include('conex.php');
 
$user  = $_POST["nombre"];
$pass  = $_POST["password"];
$email = $_POST["email"];
 
/*Validamos si el Usuario ya existe, de existir, se actualiza, sino se Ingresa*/
$sql = "Select user from tmp_usuarios where user='" . $user . "'" ;
$resUser = mysql_query($sql, $conex) or die(mysql_error());
$totUser = mysql_num_rows($resUser);
 
if($totUser>0) //Registro ya existe se actualiza
{
    $sql = "Update tmp_usuarios set pass='". $pass."',correo='". $email ."' where user='" . $user . "'";
}else{
    //Registro nuevo, se ingresa
    $sql = "Insert Into tmp_usuarios(user,pass,correo,estado) values ('" . $user ."','" . $pass ."','" . $email ."',0)" ;
}
mysql_query($sql, $conex) or die(mysql_error());
echo "1";
 
?>

Lado del Cliente

Para iniciar, lo primero que debemos hacer es agregar la librería de jQuery, para esto se recomienda siempre tener la última versión. Para agregarla, tomamos el archivo index.php y en la sección head, se agregó:

<script type="text/javascript" src="/js/jquery-1.7.1.min.js"></script>

Mostrar Datos

Una vez que cargamos la librería ya podemos comenzar a trabjar con jQuery. Como vimos, el archivo getdata.php imprime en pantalla la tabla, de tal forma, cada vez que lo mandamos a llamar, se generará la tabla de contenido. Dicha tabla, la tendremos dentro de un div, al cual podremos el id Usuarios, de la siguiente forma

<div id="Usuarios">
<?php include("getdata.php"); ?>
</div>

Podemos observar que incluimos el archivo getdata.php, el cual devuelve la tabla con el resultado de la consulta de la tabla.

Refrescar Datos

Y para el botón refrescar, tenemos

//Botón Refrescar Presionado
$("#refrescar").click(function(){
    $("#Usuarios").html("");
    $("#Usuarios").load("getdata.php", function(){});
    })

Agregar / Modificar Registros

El efecto que se logra, para que muestre el formulario visible de esa forma (un div superpuesto, se logra) con el siguiente estilo

.div_User{
    position: absolute;
    top: 25%;
    left: 25%;
    width: 50%;
    height: 60%;
    padding: 16px;
    background: #fff;
    color: #333;
    z-index:1002;
    overflow: auto;
}

Y, se ubicará en el div

<div class="div_User" id="div_User">

Y es en este div que cargaremos el contenido del formulario. Dicha acción se lleva a cabo de dos formas, dando clic en el botón Agregar o en algún usuario (de haber registros). En el caso del clic del botón,
$("#adduser").click(function(){
       $("#div_User").fadeIn();
       $("#div_User").html("<div id='cargando' style='display:none; color: green;text-align:center' width='100%' height='100%'><img width='16' height='16' src='img/ajax-loader.gif' /> Cargando...</b></div>");
       $("#cargando").css("margin-left", "auto");
       $("#cargando").css("margin-right", "auto");
       $("#cargando").css("display", "inline");
       $("#div_User").load("modificar.php", function(){
           $("#cargando").css("display", "none");
     });
    });

Antes de cargar el archivo modificar.php, ponemos el mensaje de cargando, luego usamos el método load y mandamos a cargamos el archivo modificar.php, si carga bien, se "oculta" el div cargando. Para capturar el clic en la tabla de usuarios, usamos el método live y preguntamos por el evento click

modificar.php

Dentro del archivo modificar.php, veremos que al inicio recibe los valores pasados, si no recibe nada, las variables estarán vacías, el contenido de esas variables, se pone en el value de cada input.

<?php
$user  = $_POST["user"];
$pass  = $_POST["pass"];
$email = $_POST["mail"];
 
?>
 
<form class='contacto' method='POST' action='' id="formu">
            <div><label>Usuario (*):</label><input type='text' class='nombre' name='nombre' id='usuario' value='<?php echo $user;?>'></div>
            <div><label>PassWord (*):</label><input class='nombre' name='password'  id='password' value='<?php echo $pass; ?>' type="password"></div>            
            <div><label>Tu Email (*):</label><input type='text' class='email' name='email'  id='email' value='<?php echo $email; ?>'></div>
            <div><input type='submit' value='Guardar' class='boton' name='boton' id="enviar">
            <?php if(!empty($user)) {?>
            <input type='button' value='Borrar' class='boton' name='boton' id="Borrar">
            <?php }?>
            <input  type='button' value='Cerrar' class='boton' name='boton' id="Cerrar">
            </div>
</form>

Botón Enviar Datos (Actualizar o Modificar

En el evento clic del botón enviar, primeramente usamos preventDefault(), para evitar que se ejecute el Submit del formulario. Luego para cada input preguntamos por el valor y si está vacío, se agrega un spam con la clase error, al final de cada validación, se usa el return false, para evitar que siga a la siguiente instrucción.

Luego de validar todo, utilizamos ajax para enviar los datos al archivo saveuser.php, para capturar los valores del formulario, se utiliza el método serialize de jQuery.

En el ajax, se pone el especifica el tipo (en nuestro caso POST), en url, se especifica el destino (saveuser.php), si sucede algún error (como que no exista el archivo especificado en url), está la sección error:, en data ponemos los valores serializados del formulario.

Si el envío es satisfactorio, se utiliza la sección success, la variable data, contiene lo que envíe de respuesta el archivo saveuser.php, para esto, utilizamos el echo "1", si data contiene el valor 1, se asume que todo salió bien, así que se procede a "repintar" la tabla de usuarios.

/*Evento Click Botón Enviar*/
 $("#enviar").click(function(evento){
     evento.preventDefault(); //Evitamos que el formulario se vaya
 
     /*Validación*/
     var emailreg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;   //Creamos las reglas para validar el correo
     $(".error").fadeOut().remove();
 
     if ($("#usuario").val() == "") { 
        //alert("Usuario Inválido");
        $("#usuario").focus().after('<span class="error">Usuario Inválido</span>');
        return false;
     }
 
     if ($("#password").val() == "") { 
        //alert("Password Requerido");
        $("#password").focus().after('<span class="error">Password Requerido</span>');
        return false;
     }
 
    if ($("#email").val() == "" || !emailreg.test($("#email").val())) {
        //alert("Dirección de Correo Inválida");
        $("#email").focus().after('<span class="error">E-Mail Inválido</span>');
        return false;       
    }
    /*Fin Validación*/
 
    //Determinanos los datos del formulario y los serializamos
    var datos = $("#formu").serialize();
    //alert(datos);
    // Enviamos el formulario usando AJAX
        $.ajax({
            type: 'POST',
            url: 'saveuser.php',
            error: function(data){
                //Si sucedió algo, se notifica
                    $(".result_fail").fadeIn();
                    $(".result_fail").html("Error Procesando Datos");
                },
            data: datos,
            // Mostramos un mensaje con la respuesta de PHP
            success: function(data) {
                if(data==1){
 
                    /*Reconstruimos la tabla*/
                    $("#Usuarios").html("");
                    $("#Usuarios").load("getdata.php", function(){});
                    /*Fin Reconstruir la tabla*/
 
                    $("#div_User").hide();
                }
                else{
                    $(".result_fail").fadeIn();
                    $(".result_fail").html("Error " . data);
                    return false;
                    }
             }
        });
});
 /*Fin Evento Click Botón Enviar*/

Botón Borrar

De la misma forma, sucede con el botón borrar.

/*Evento Click Botón Borrar*/
$("#Borrar").click(function(){
 
    /*Confirmar si se desea borrar el registro*/
    var Resp = confirm("Eliminar Registro para " + $("#usuario").val());
 
    if(Resp){
            /*Escogió opción ACEPTAR*/
            //Determinanos los datos del formulario y los serializamos
           var datos = $("#formu").serialize();
           // Enviamos el formulario usando AJAX
           $.ajax({
               type: 'POST',
               url: 'deluser.php',
               error: function(data){
                   //Si sucedió algo, se notifica
                       $(".result_fail").fadeIn();
                       $(".result_fail").html("Error Eliminando Registro");
                   },
               data: datos,
               // Mostramos un mensaje con la respuesta de PHP
               success: function(data) {
                   if(data==1){
 
                       /*Reconstruimos la tabla*/
                       $("#Usuarios").html("");
                       $("#Usuarios").load("getdata.php", function(){});
                       /*Fin Reconstruir la tabla*/
 
                       $("#div_User").hide();
                   }
                   else{
                       $(".result_fail").fadeIn();
                       $(".result_fail").html("Error " . data);
                       return false;
                       }
                }
           });      
        }
 
    })
 /*Fin Evento Click Botón Borrar*/

Conclusiones

Espero que este tutorial les sea de mucha utilidad, es bastante básico, pero traté que quedara lo más completo posible. Sígannos en Twitter (o Facebook), para descargar los fuentes, sólo deben compartir este contenido en alguna de las redes sociales que se indica en el botón siguiente e inmediatamente saldrá el link de descarga.  La aplicación pedirá permiso para poder postear.


Hay detalles concernientes a la seguridad, pero este pequeño tutorial les sea de utilidad.

Enlace Relacionado

Tutorial ABC con jQuery y MySQL

"Enseñar es la mejor forma de aprender"


jueves, 29 de mayo de 2014

Poner Larry de Twitter a Volar en tu Web o Blog


#Larry #Twitter #Fly #Web #Blog #Social #Script #Gadget

¿Te gustaría poner en tu Blog o Web a Larry? Es muy sencillo con este script o gadget, será sólo cosa de copiarlo, personalizarlo y listo.



 <script src="http://plantillasgratis.comuv.com/disemucho/pajaro_twitter_navidad/twitter/disemucho.js" type="text/javascript">
</script><script type="text/javascript">
//<![CDATA[
        var birdSprite='http://u.jimdo.com/www21/o/s4e9df44a0ad8ccd8/img/iffeafe7e991f963f/1341590653/std/image.png';
        var targetElems=new Array('img','hr','table','td','div','input','textarea','button',
'select','ul','ol','li','h1','h2','h3','h4','p','code','object','a','b','strong','span');
        var twitterAccount = 'http://twitter.com/#!/tu usuario';
        var twitterThisText ='Sigueme en Twitter';
        tripleflapInit();
//]]>
</script> 

Y listo, vas a tu web y pegas este código o desde blog, ve al diseño y das clic en agregar gadget, escoges el HTML/JavaScript y ahí pegas el script anterior.  Ten en cuenta que debes poner tu usuario (donde lo indica)

Espero te sea de utilidad

"Enseñar es la mejor forma de aprender"

martes, 27 de mayo de 2014

Botón Imprimir - jQuery Plugin


Introducción


jQuery printing plugin es un plugin muy bueno con el que se puede agregar la opción de imprimir a nuestras aplicaciones web.
La forma de funcionar es bastante sencilla, basta con tener un botón, que le pongamos ya sea un class o un id. Dicho botón, puede ser algo con un plugin o un simple enlace, al que le ponemos:

<a href="https://www.blogger.com/iframe.html" id="btnPrint">Print!</a>

Lo que si debemos notar, que se le pasa en el href del enlace, la ruta del archivo a imprimir que bien puede ser un html o algu en php que querramos procesar, para formatear y esas cosas.
Luego el uso es sencillo.

$("#btnPrint").printPage()
Y listo, también podemos mejorarlo con parámetros más "avanzados":


$("#imprimir").printPage(
{
  url: "opciones/opc_suc_set.php",
  attr: "href",
  message:"Su documento está siendo generado"
}
);

Enlaces relacionados

Demo
Descarga

Enseñar es la mejor forma de aprender

lunes, 26 de mayo de 2014

Common Table Expression - SQL Server



Una CTE (Common Table Expression - Expresión de Tabla Común), se puede considerar un conjunto de resultados temporal que se define en el ámbito de la ejecución de una instrucción única SELECT, INSERT, UPDATE, DELETE o CREATE VIEW. Una CTE es similar a una tabla derivada en que no se almacena como un objeto y dura sólo el tiempo que dura la consulta. A diferencia de una tabla derivada, una CTE puede hacer referencia a sí misma y se puede hacer referencia a ella varias veces en la misma consulta.

Al igual que una TVF nos ayuda entre otras cosas a simplificar las consultas grandes, teniendo una mejor visión de la consulta entera.  Las CTE's, también cumplen este objetivo, pero su tiempo de vida es mucho más corto, ya que no se guarda como un objeto de la base de datos, sino que dura el ámbito de la ejecución de la instrucción, la cual puede estar contenida en un SP (Store Procedure) o una consulta general.

En mi caso, ¿dónde las he utilizado? Cuando debo hacer una consulta bastante extensa, que requiere que filtre información sobre datos ya filtrados, básicamente implementando recursividad o reutilizando la consulta anterior. Para los que han programado con Visual FoxPro, es equivalente al manejo de Cursores, con los cuales, la información se obtenía en una consulta (Cursor) y luego ese cursor se podía filtrar y/o utilizar para otra operación.

El uso de una CTE ofrece las ventajas de una legibilidad mejorada y la facilidad de mantenimiento de consultas complejas. La consulta se puede dividir en bloques de construcción lógicos simples e independientes. Estos bloques simples se pueden usar para crear CTE provisionales más complejas hasta que se genere el conjunto de resultados finales.

Las CTE se pueden definir en rutinas definidas por el usuario, como funciones, procedimientos almacenados, desencadenadores o vistas.

Sintaxis


WITH expression_name [ ( column_name [,...n] ) ]
AS
( CTE_query_definition )
 
Al importante que debo destacar es la utilización de un punto y coma (;) al inicio del CTE, ya que SQL Server enviará un error indicando que la última consulta anterior al CTE debe terminar con ;

También se pueden anidar CTE, con la siguiente sintaxis.

;With C1 AS
(
 Select ...
 From T1 
 Where ...
),
C2 AS
(
 Select ...
 From C1 
 Where ...
)
Select ...
  From C2
Where ...;

Ejemplos

En el siguiente ejemplo se muestra el número total de pedidos de venta por año para cada representante de ventas en Adventure Works Cycles:

;WITH Sales_CTE (SalesPersonID, SalesOrderID, SalesYear)
AS
(
    SELECT SalesPersonID, SalesOrderID, YEAR(OrderDate) AS SalesYear
    FROM Sales.SalesOrderHeader
    WHERE SalesPersonID IS NOT NULL
)
SELECT SalesPersonID, COUNT(SalesOrderID) AS TotalSales, SalesYear
FROM Sales_CTE
GROUP BY SalesYear, SalesPersonID
ORDER BY SalesPersonID, SalesYear;

Más ejemplos por parte de Microsoft, pueden tener en este link.

Un ejemplo práctico, es este SP que realice a inicio del 2014, en el cual tenía que extraer las facturas pendientes de pago, pero por mes.

-- =============================================
-- Author:  Ing. DEBS
-- Create date: 13/02/2014
-- Description: Devuelve por mes (año actual)
--    las facturas pendientes de los proveedores
-- =============================================
ALTER PROCEDURE [Exo].[GetFCxPrvxYear]
 @cYear varchar(4)=''
AS
BEGIN
 /*Declare @cYear as varchar(4);
 Set @cYear = Convert(varchar(4),Year(GetDate()));
 */
 IF @cYear = ''
 BEGIN
  Set @cYear = Convert(varchar(4),Year(GetDate()))
 END

 ;With CTE1  --Llama la CTE y sus valores y convierte a C$ todo
  as
 (
 Select cDescPrv,cCodPrv,
  case when cCodMon='C$' THEN nMonto ELSE Round(nMonto * nTC,2) end as nMonto,
  case when cCodMon='C$' THEN nExonerado ELSE Round(nExonerado * nTC,2) end as nExonerado,
  case when cCodMon='C$' THEN nSaldo ELSE Round(nSaldo * nTC,2) end as nSaldo,
  left(YearMes,4) as cYear,Right(YearMes,2) as cMes
  from Exo.GetFCSaldos() 
  where nSaldo<>0
  and nMonto>=0 and nExonerado>=0 and nSaldo>=0
 ),-- CTE2 Ubica cada valor en el mes correspondiente
 CTE2 (cDescPrv,cCodPrv,Saldo_Ant,Ene,Feb,Mar,Abr,May,Jun,Jul,Ago,Sep,Oct,Nov,Dic) 
  as
 (
  Select cDescPrv,cCodPrv,
   case when cYear < @cYear then Sum(nSaldo) ELSE 0.0 END,
   Case when cMes = '01' and cYear = @cYear then Sum(nSaldo) else 0.00 end,
   Case when cMes = '02' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '03' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '04' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '05' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '06' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '07' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '08' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '09' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '10' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '11' and cYear = @cYear  then Sum(nSaldo) else 0.00 end,
   Case when cMes = '12' and cYear = @cYear  then Sum(nSaldo) else 0.00 end
  from CTE1
  group by cDescPrv,cCodPrv,cYear,cMes
 ) --Se procede a sumar todo y listo
 Select cDescPrv,cCodPrv,Sum(Saldo_Ant) as Anterior,
  Sum(Ene) as Enero,
  Sum(Feb) as Febrero,
  Sum(Mar) as Marzo,
  Sum(Abr) as Abril,
  Sum(May) as Mayo,
  Sum(Jun) as Junio,
  Sum(Jul) as Julio,
  Sum(Ago) as Agosto,
  Sum(Sep) as Septiembre,
  Sum(Oct) as Octubre,
  Sum(Nov) as Noviembre,
  Sum(Dic) as Diciembre,
  Sum(Saldo_Ant + Ene + Feb + Mar + Abr + May + Jun + Jul + Ago + Sep + Oct + Nov + Dic) as Total
 from CTE2
 where
  (Saldo_Ant + Ene + Feb + Mar + Abr + May + Jun + Jul + Ago + Sep + Oct + Nov + Dic)<>0
  group by cDescPrv,cCodPrv
  order by cDescPrv,cCodPrv
END


Una ejecución a este SP, es algo así:

Conclusión

Las CTE's son muy útiles para poder aplicar recursividad a la información que queremos filtrar, esto es, aplicar ciertas operaciones (o filtro) sobre un conjunto de registros que previamente extrajimos (o consultamos) de la BD.

Como verán en el ejemplo que puse ya al final, utilicé dos CTE, la primera (CTE1) se encarga de poner todos los montos en moneda nacional (de no estarlo), a partir de los datos de una TVF (Exo.GetFCSaldos()) así como filtrar únicamente los registros que aún tienen saldo, además de poner los dos primeros dígitos del mes, luego en la segunda CTE (CTE2) se realiza la sumatoria por mes de cada registro del año correspondiente, asignándoles el nombre del mes.  Al final, se muestran los datos, a partir de la CTE2 y se totaliza por registros.  Puede que la solución es bastante compleja y existen métodos más sencillos, pero traté de ponerles una aplicación práctica de CTE.

Para más información sobre CTE's, pueden visitar los siguientes sitios:
Gracias por haber tomado el tiempo de leer este artículo, espero te sea de utilidad y de serlo, favor compartirlo.  Igual, si tenés alguna duda, comenta en esta publicación.

"Enseñar es la mejor forma de Aprender"


 
>