viernes, 19 de junio de 2015

ejemplo paso a paso de la clausula MERGE de SQL en Oracle,

Haremos un ejemplo de la funcionalidad MERGE que a grandes rasgos puede actualizar, borrar e insertar en una sola instrucción. 

Si antes quieres revisar la documentación de la claúsula MERGE Database SQL Reference, podrás conocer los requisitos y el detalle de la sintaxis, que yo resumiré así:

MERGE INTO TABLA1 USING (TABLA2) ON (CONDICION DE UNION) WHEN MATCHED THEN UPDATE SET columna = expresion WHERE (CONDICION WHEN-MATCHED) DELETE WHERE (CONDICION DELETE) WHEN NOT MATCHED THEN INSERT (columas) VALUES (valores) WHERE (CONDICION NOT-MATCHED)

 

  • TABLA1 puede ser una tabla o una vista y se les conoce como tabla DESTINO
  • TABLA2 puede ser una tabla, vista o un subquery, es llamada también ORIGEN, pues de ahí se van a tomar los datos a actualizar o insertar
  • CONDICION DE UNION liga ambas tablas
  • la sub-sentencia UPDATE, después del SET es muy similar a la tradicional, es decir, se pueden actualizar varias columnas, pero me parece que hay algunas columnas como la usada para la union que parece no pueden actualizarse, eso revisarlo en la documentación.
  • le DELETE es una subclausula de WHEN MATCHED THEN UPDATE SET y en cualquier caso, los WHERE se marcan como opcionales.
  • el INSERT que no tiene INTO, es similar a la sentencia original, con columnas separadas de los valores y separado por VALUES, y sólo va con la clausula WHEN NOT MATCHED THEN INSERT.

Para nuestro ejemplos usaremos las tablas del módelo HR que viene en la versión Express de Oracle 11g.

Primero crearemos una tabla auxiliar llamada bonuses, pongo un truncate en la lista de las siguientes instrucciones por si desean repetir el ejemplo más de una vez, la llenamos y le quitamos algunos registros para que sea más fácil de ver el resultado:


CREATE TABLE bonuses (employee_id NUMBER, bonus NUMBER DEFAULT 100); truncate table bonuses; INSERT INTO bonuses(employee_id) (SELECT e.employee_id FROM employees e GROUP BY e.employee_id); delete from bonuses where employee_id < 150 or employee_id between 156 and 165 or employee_id > 170; SELECT * FROM bonuses;










Después de ejecutar el script anterior nos quedan los siguientes registros:

EMPLOYEE_ID      BONUS
----------- ----------
        150        100
        151        100
        152        100

        153        100
        154        100
        155        100
        166        100
        167        100
        168        100
        169        100

        180        100
        181        100
        182        100

 13 filas seleccionadas
Y ahora vamos a ejecutar el siguiete MERGE y posteriormente revisaremos los registros que quedan en el tabla (he remarcardo en rojo los que ya no aparecerán):

MERGE INTO bonuses D USING (SELECT employee_id, salary, department_id FROM employees WHERE department_id = 80) S ON (D.employee_id = S.employee_id) WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01 DELETE WHERE (S.salary > 8000) WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus) VALUES (S.employee_id, S.salary*.5 ) WHERE (S.salary <= 8000);







Que nos arroja:
19 filas fusionadas.
Pero si volvemos a ver el listado de la tabla bonues, ya no hay 13 filas, ni 19, depués del MERGE hay 17.  Y es que hizo las tres operaciónes antes descritas:
  1. Se eliminaron los que están remarcados en rojo del listado anterior.
  2. Se actualizaron los que están remarcados en amarillo del siguiente listado.
  3. Se insertaron los remarcados en verde del siguiente listado
  4. Y no se vieron afectados los que están de color azul.
EMPLOYEE_ID      BONUS
----------- ----------
        153        180
        154        175
        155        170

        159       4000
        160       3750
        161       3500
        164       3600
        165       3400

        166        164
        167        162

        171       3700
        172       3650
        173       3050
        179       3100

        180        100
        181        100
        182        100


 17 filas seleccionadas

Iremos desglozando la sentencia, y en particular todo gira alededor de los empleados del departamento 80.
MERGE INTO bonuses D USING (SELECT employee_id, salary, department_id FROM employees WHERE department_id = 80) S ON (D.employee_id = S.employee_id) WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01 DELETE WHERE (S.salary > 8000) WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus) VALUES (S.employee_id, S.salary*.5 ) WHERE (S.salary <= 8000);







Iremos desglozando la sentencia, y en particular todo gira alededor de los empleados del departamento 80.

Si son del departamento 80, hay dos clausulas que ejecutar, una, actualizar su bono con el uno porciento de su salario adicional y dos, borrar los que ganen más de 8,000.
MERGE INTO bonuses D USING (SELECT employee_id, salary, department_id FROM employees WHERE department_id = 80) S ON (D.employee_id = S.employee_id) WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01 DELETE WHERE (S.salary > 8000) WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus) VALUES (S.employee_id, S.salary*.5 ) WHERE (S.salary <= 8000);







Si para el caso de cuando los empleados no son del departamento 80, hay una clausula INSERT que ejecutar, misma que pondrá como bono la mitad del sueldo, siempre que sus salarios sean menores de 8,000.

MERGE INTO bonuses D USING (SELECT employee_id, salary, department_id FROM employees WHERE department_id = 80) S ON (D.employee_id = S.employee_id) WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01 DELETE WHERE (S.salary > 8000) WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus) VALUES (S.employee_id, S.salary*.5 ) WHERE (S.salary <= 8000);









Si desas corroborar que los resultados son coherentes, podrías ayudarte de las siguientes sentencias:

  1. registros eliminados

    SELECT
    * FROM bonuses WHERE employee_id in (SELECT employee_id FROM employees WHERE department_id = 80 and salary> 8000); --registros que fueron eliminados
  2.  registros que no cambiaron

    SELECT
    * FROM bonuses WHERE employee_id in (SELECT employee_id FROM employees WHERE department_id != 80 and salary <= 8000); -- registros no modificados
  3. registros que si cambiaron, algunos porque fueron insertados otros sólo cambió el valor.

    SELECT * FROM bonuses WHERE employee_id in (SELECT employee_id FROM employees WHERE department_id = 80 and salary <= 8000) order by 1;

martes, 12 de noviembre de 2013

Diccionarios offline en Android [express]

Nunca está de más tener a la mano un diccionario (o incluso, mejor varios), por eso llevo en mi teléfono (uno de los primeros que traían sistema Android 1.5) algunos, entre ellos diccionarios Español-Español, Español-Inglés e Inglés-Inglés.


  • Un programa para descomprimir archivos en formato 7z
    • 7zip 
    • PeaZip 
    • WinRAR o WinZip podrían funcionar pero seguro los de los incisos anteriores y ambos son gratis.
  • Descargar el archivo dictdata.7z, descomprimir el contenido y transferirlo a la tarjeta de memoria (microSD) de tu celular, cuidando que dicho contenido se ubique en la carpeta GoldenDict. (para la descarga del archivo, se les solicitará una llave, esta está en dos piezas a continuación, favor de unirlas para poder usar la llave completa)
    •  RCRvJg4_Ap9580L75Xfo0z
    • h6cH1XnlUybEts9pa544U
  • Instalar la aplicación GoldenDict para Android.desde el Google Play. (también existe una versión para Windows que funciona de forma similar). La única limitante de la versión Free para Android sólo soporta tener hasta 5 diccionarios que son los que vienen en el paquete. GoldenDict trabaja muy bien con archivos de diccionario .BGL entre otros.

lunes, 21 de noviembre de 2011

mapas offline de la Ciudad de México para Android

La Ciudad de México o el DF como le llamamos nosotros, es enorme y de una complicada geografía, casi nadie la conoce de todo a todo, pero todavía mayor es la Zona Metropolitana del Valle de México que incluye más de 70 municipios, así es fácil perderse, pero ya no más, no si tienes un teléfono con Android, y lo mejor de todo, sin necesidad de gastar por el consumo de datos, y con zoom en escalas de 10 a 18.

requisitos:
  1. bajar y descomprimir el archivo DF.zip (DF.sqlitedb ~400MB en 4 partes) de mapas del DF, en esa misma liga se encuentan algunos archivos .apk, referentes al siguiente punto.
    Actualización: ahora también puedes bajar el archivo DF.sqlitedb directo en un sólo archivo, cuyo MD5 debe ser 3eb52a7a0e92575fd8e1dc5a9fdefe9a.
  2. instalar RMaps, no te preocupes si en el Android Market no está disponible para tu versión de Android, puedes intentar con alguna versión anterior. En el caso de Android 1.5 las versiones más recientes de RMaps no funcionan del todo bien, así que recomiendo ir probando las versiones de RMaps empezando con la versión 0.8.4.
  3. Recomendación: Para descomprimir los archivos usa el PeaZip que entre sus muchas bondades además es gratis.

Como activar los mapas en tu celular.
Una vez copiados los mapas (DF.sqlitedb) a la memoria MicroSD de tu celular en la ruta /rmaps/maps, abrimos el RMaps y seguimos los siguientes pasos.
  1. Presionamos "MENU>More>Settings>User defined maps".
  2. Seleccionamos el mapa (DF.sqlitedb)
  3. A continuación presionamos "Enable map".
  4. Nos Regresamos a la pantalla principal de RMaps.
  5. Presionamos "Menu>Maps" y en la lista ahora aparecerá el mapa que hemos descargado y activado, lo seleccionamos y listo ¡a disfrutar el DF offline!

 Referencias

yo usé el Mobile Atlas Creator versión 1.7, también intenté usar el SAS.Planet, pero no generaba mapas indexados.
http://androidapprmaps.blogspot.com/2010/04/rmaps.html
http://robertdeveloper.blogspot.com/2009/08/rmaps.html
http://www.wupload.com/file/2598878002/DF.sqlitedb


sábado, 9 de enero de 2010

CFE en mis vacaciones

Por fin tuve vacaciones de invierno, sí, al fin llegaron esos 10 días hábiles que soñé por 2 años :D ... la verdad me la pasé bien: relajado, jugando, descansando y buscando cosas que aprender ... pero ahora me quiero quejar de la CFE porque estuvo ausente muy presente en mis días de descanso y hasta tuvimos que hacer su chamba.

Antes de irme a mi rancho anduvo fallando la luz en mi casa, llamé al 071 y me dijero que ya había un reporte de la falla y que según ya estaba una cuadrilla en proceso de arreglarla y hasta me dijeron que andaban en una calle aledaña. Sinceramente me quedé con una buena impresión del servicio de la CFE, pero ...

Ya en el rancho,al segundo día también se fue la luz, no completamente, afortunadamente aunque bajo, el voltaje era suficiente para hacer funcionar la lap y el psp :D (uff!) ... pero entonces me dije a mi mismo: "llámales, al fin que los de la CFE si contestan", más aún, cuando leí en sus recibos que según ellos tienen "tiempos de respuesta" bien definidos: 2, 4 o 10 horas en reestablecer el suministro dependiendo de la intensidad del problema.

Y ahí me tienes llamando desde el celular ... tardan un poco en contestar ... por fin contestan ... me preguntan el motivo de la llamada y cuando me piden mis datos me preguntan: "¿su código postal?" ... mmm no hay, ya les había comentado que es una ranchería, y en el recibo no dice ningún código postal, sólo el nombre de la comunidad y ya, también me pidieron el número del medidor y un número de servicio que si vienen en el recibo, y pensé: .oO(mañanita a más tardar tendremos luz nuevamente ...)

Al otro día seguíamos igual, con la luz a medias ... fuimos a Tulancingo y volvimos a reportar la falla, esperamos un día más ... para nada ...

Al día siguiente vimos como unos vecinos alrededor de un poste intentaban subir la "cuchilla" así que nos acercamos para ver si podíamos ayudar, fuimos por una escalera a la casa para hacer las maniobras más fáciles y resultó que efectivamente el fusible se había quemado. Por suerte uno de los vecinos es encargado de la electricidad en una fábrica cercana que tiene su propio transformador y él tenía los listones para reemplazarlo, un rato más tarde ya teniamos luz ... éramos felices!

Poco nos duró el gusto, creo que día y medio y otra vez nos quedamos sin luz, así que no lo pensamos mucho y fuimos a ver si era el mismo problema. Y sí, la cuchilla se había bajado.

Con los repuestos necesarios y las herramientas adecuadas (algunas hechas por nosotros mismos para la ocasión) fue cuestión de unos 15 minutos reestrablecer el suministro. Me imagino que una camioneta de CFE equipada no le lleva más de 5 minutos en solucionarlo, pero el problema es que nunca llegaron.

Sí, el servicio es en una ranchería, pero por mucho no es inaccesible, y si la CFE se supone una "empresa de clase mundial" creo que
aún le falta mucho ... para acabarla que ahora que regresé, en el cine hubo un apagón y no pude terminar de ver la película que quería.

miércoles, 3 de diciembre de 2008

Trabaja como Ninja Javascript

Imagino que a estas alturas todos conocen el mensajero instantáneo meeb.oO, un mensajero versión Web, que es compatible con la mayoría de los sistemas de mensajería instantánea.

Desde que salió se mostró muy novedoso, porque fue de los primero servicios que explotaban AJAX en todo su esplendor ... haciendo prácticamente su propio manejador de ventanas dentro de una ventana del navegador.

Inmediatamente quise ver cómo estaba hecho Meebo, y al revisar su código, había un comentario dentro de la programación donde te invitaban a enviar tu curriculum vitae a la dirección secretjobs de meebo.com.

Más recientemente encontré que tiene una sección de ofertas de empleo y donde anuncian que solicitan un "javascript engineer (javascript ninja)" y ahí mismo te dejan un breve cuestionario para medirte un poco y ver si tienes madera para el puesto. Son tan sólo 5 preguntitas y yo sólo pude medio contestar una, la 4:

4. Write a one-line piece of JavaScript code that concatenates all strings passed into a function:


function concatenate(/*any number of strings*/) {
var string = /*your one line here*/
return string;
}

Y esta es mi solución, que quizá no sea lo que esperaban, pero lo hace :D

function concatenate() {
for (var string='',i=0; i < arguments.length; string+=arguments[i++]);
return string;
}


Si pueden contestar las otras cuatro preguntas quizá les interese mudarse a Mountain View a tirar algunas patadas.

martes, 7 de octubre de 2008

¡no marches!

A un año de estar trabajando sobre la Avenida Juárez casi esquina con Reforma, me han tocado ver todo tipo de marchas, no recuerdo semana en la que no haya habido una marca, aunque quizá si las haya habido, sin embargo se compensa con semanas en las que hay 2, 3 o más ...

Ya me aprendí el :"de norte a sur ... de este a oeste ... ganaremos esta lucha, cueste lo que cueste" o "presos políticos: ¡libertad!" y otros gritos "combativos" ... que si el gobierno federal, que si el local, que si la SEP, que SEGOB, que la SSP, y hasta una que llegó a la Contraloría denunciando abusos/extorsiones en el INVI ... en fin ... ya estoy harto .... porque dudo mucho que haya habido una marcha que haya solucionado algo... ¡Ah! y casi lo olvido, la mega "marcha en contra de las marchas" motivada por panistas y y llena de acarreados de las secretarías federales, con sus pancartas hechas en computadora y que caminaban ordenadamente por las banquetas, claro, no eran más que unas decenas de personas ...

Hoy, muy a mi pesar tuve que aguantar cerca de 3 horas de gritos, mentadas, desfile y más de una hora extra de plantón ... para todos aquellos que tienen duda de quienes era, eran "antorchistas" de varias partes del país y que su principal grito era contra la SEGOB buscando la libertad de presos políticos en el estado de Querétaro.

Sin embargo la fuerte exposición a las marchas te vuelve inmune y deja completamente de lado los "reclamos" para dar pie a otros aspectos que se llevan la atención, como hoy, que fueron las bandas musicales marchantes que acompañaban al contingente ... no tocaban muy mal pero, obvio, tampoco bien, sin embargo se agradece por un momento que en lugar de gritos se oiga algo un poco más armónico, ojalá la mayoría fueran así ...

Pero entonces que me acordé de bandas como la de los Delfines Marching Band y la de las Aguilas Doradas Marching Band, una de Xalapa y la otra de Puebla respectibamente, que han representando a México en distintos festivales internacionales o en el desfile de las rosas en EUA.

Les dejo dos fotos de marchas, una la marcha de micros (espero nutrir la anticultura del buen Maicol), y una de la banda marchante con tabla gimnástica:

lunes, 6 de octubre de 2008

yoo en el 2001 en google

Como (auto)homenaje a su décimo aniversario, Google nos regresa al pasado, inaugurando una sección que nos remite a su visión de la red en enero de 2001.

La sección es Google Search 2001: http://www.google.com/search2001.html.

Y como todo buen egocentrísta le pregunté qué hacía yo en ese entonces :D ..