En el artículo anterior vimos el uso más básico de la clausula SELECT de SQL, sin embargo apenas arañamos la superficie en cuanto a la cantidad de tipos de selecciones que podemos hacer.
En este segundo artículo vamos a explorar las posibilidades de los comandos de grupo que nos permiten realizar operaciones sobre las filas que devolvemos (como devolver una suma, o el número de filas) así como el uso de la orden GROUP BY que está íntimamente relacionado con lo anterior. Por otro lado exploraremos las intersecciones que se pueden realizar entre consultas (JOIN).
En la entrega anterior vimos una pequeña introducción al comando SELECT de SQL. En él vimos el uso más básico de este comando, es decir, su uso para realizar consultas sencillas de selección y obtener datos de una o varias tablas.
En un 90% de las situaciones ese será el tipo de consultas que utilicemos, sin embargo en ocasiones, ese 10% restante, necesitamos algo más preciso, un comando de selección que nos permita obtener justamente los datos que necesitamos y que no se refieren directamente a una tabla sino que son, quizá, suma de dos o más tablas, intersecciones, obtener los resultados agrupados, ordenados, etc... La sentencia SELECT nos permite hacer todo este tipo de cosas.
Como ya vimos en la introducción anterior la sintaxis general de una consulta de selección SELECT es la siguiente:
SQL son las siglas de Structured Query Language, que traducido significa Lenguaje de consulta estructurado y que es el estandar de facto para acceso a base de datos.
En lenguaje SQL surgió a raiz de la creación en IBM durante la decada de los 70 de un sistema de base de datos llamado "System R". Para manipular y recuperar datos de dicho sistema se diseño un lenguaje llamado SEQUEL (Standard English Query Language) que finalmente se convertiría en SQL (la historia del cambio de nombre es curiosa y se debió a que el nombre SEQUEL ya estaba registrado por otra compañía, aún así hoy en día una de las pronunciaciones para SQL es, precisamente SEQUEL).
DirectX. Si has llegado a este artículo por que quieres programar tu propio Quake 4 en tus ratos libres deja que te saque de tu error, jamás vas a poder hacerlo. Antiguamente los juegos los programaban uno o dos programadores que trabajaban unos meses y conseguían crear un juego (mejor o peor). Actualmente los juegos los programan equipos relativamente grandes de personas con diversas especialidades (no hace falta solo programar sino también diseño gráfico, composiciones musicales, efectos de sonido, etc).
¿Entonces que voy a poder hacer? Bueno, quizá no consigas programar un juego de última generación pero quizá si puedas programar algún pequeño juego, conseguir un simulador físico convincente o sencillamente impresionar a las visitas (y de paso mejorar tu curriculum). Además programar gráficos en 3D es bastante gratificante (una vez las cosas van funcionando) puesto que el resultado es más "gráfico".
Managed DirectX se traduce como DirectX "Asistido" que me parece un termino muy feo en español así que simpre utilizaré el termino ingles que me suena mucho más apropiado.
En Delphi existen dos conceptos que suelen surgir bastante a menudo, tiempo de diseño (design time) y tiempo de ejecución (run time).
El concepto de tiempo de diseño se refiere, de alguna forma, al sistema de diseño del IDE de Delphi, es decir, la parte en la que arrastramos forms, botones, campos de texto, etc ... y los situamos en las posiciones que queremos, es decir, realizamos el diseño de nuestra aplicación.
El tiempo de ejecución se refiere al tiempo durante el cual el programa esta ejecutando, es decir, el tiempo de vida de la aplicación.
Cuando estamos creando nuestra aplicación, la forma más natural de definir el aspecto de esta ir creando los forms que necesitemos e ir añadiendo botones, campos de texto y otros y situandolos en pantalla hasta encontrar el diseño que buscamos.
Cada vez que creamos un form delphi automáticamente crea una nueva unidad (.pas) y un nuevo fichero de descripción de formulario (.dfm). El IDE de Delphi se encarga de ir modificando estos dos ficheros automáticamente para reflejar los cambios que vamos haciendo. Por ejemplo, vamos a echar un vistazo a un dfm de ejemplo que contiene un Form (Form1) que a su vez contiene un TMemo y TButton.
Hace poco me he encontrado en el trabajo con un programa que estaba haciendo estaba teniendo pérdidas de memoria, no demasiada cada vez pero si lo suficiente como para convertirse en un problema a medio plazo.
Cuando te encuentras un problema de consumo de memoria lo más habitual es mirar el código de la zona en la que piensas que puede estar el problema intentando encontrar el lugar donde consumes memoria que luego no vas a liberar, o bien recurrir a algún programa de monitorización de memoria que te ayude a encontrar dichos problemas (yo no he tenido suerte con ellos).
Un pipe o tubería es una estructura de datos que representa un canal de comunicación con una estructura de tipo FIFO (primero en entrar, primero en salir).
La denominación de tubería (en ingles pipe) viene del concepto de que los datos que introducimos o empujamos por un extremo de la tubería "aparecen" en el extremo contrario. Si realizamos una operación de lectura en la tubería y no hay datos en esta el hilo llamante se quedará bloqueado hasta que haya datos. Si realizamos una escritura en la tubería y esta ha alcanzado su tamaño máximo el proceso que desea escribir en la tubería se quedará bloqueado hasta que algun lector saque un dato.
Cuando hablamos de la distancia entre dos puntos solemos referirnos a la distancia en linea recta entre esos dos puntos. Sin embargo cuando queremos calcular la distancia entre dos puntos situados sobre una esfera (en mi caso dos puntos sobre la superficie de la tierra) estamos hablando de la distancia geodésica entre esos dos puntos.
Solo pongo esta función aqui porque en el trabajo necesito calcular la distancia geodésica entre dos puntos y estaba usando una librería COM que era excesivamente lenta para lo que necesitaba (4 milisegundos frente a 1 microsegundo). No tengo ni idea de como funciona lo que pongo debajo (si tengo tiempo lo miraré más detenidamente y trataré de explicarlo (hasta donde yo se consiste en aplicar la formula de la longítud de arco de una circunferencia (aplicando además en este caso una desviación, ff, por el achatamiento de la tierra) dadas la latitud y longitud de cada punto)). La función está adaptada de un código de Visual Basic de Jay Tanner para poder usarla en Delphi.
En determinadas ocasiones necesitamos saber el tiempo que tarda una determinada rutina en ejecutar generalmente por que creemos que un determinado fragmento esta tardando más de lo esperado y queremos saber donde está el cuello de botella o por que tenemos alguna aplicación que tiene establecidos unas limitaciones de rendimiento que queremos cumplir.
Hay varias funciones en el la libreria kernel32.dll de windows que pueden ayudarnos en nuestra tarea. GetTickCount (y GetTickCount64) y la combinación de QueryPerformanceCounter y QueryPerformanceFrecuency.
First thing we have to keep in mind when we try to get the CPU load for windows processes is the fact that Windows isn't magically calculating that percentage.
In fact, instead of maintaining a percentage that wouldn't be useful, Windows, keeps track, for each process, of the time that the process has been executing on user mode, the time it has been executing in kernel mode and the instant the process was created.
With all that data we can't just obtain the instant CPU load for a process. We can get the average CPU load for the process by a simple arithmetic calculation (AvgTime = User Time + Kernel Time / Actual Time - Creation Time). We could say that instantaneous CPU load value doesn't exist, just like Electric Potential :D
Keep reading ... ;)