domingo, 22 de mayo de 2016

SQL AVANZADO (III). USO DE LA EXPRESION CASE EN SENTENCIAS UPDATE INFORMIX - Advanced Informix Sql (III). Using the CASE expression in a UPDATE sentence

En entradas anteriores hemos visto el uso de la función CASE en una SELECT, pero su uso puede ser muy útil también en una sentencia UPDATE.
Por ejemplo, imaginemos que queremos aumentar el precio de nuestros artículos en un porcentaje distinto según la sección a la que pertenezca el artículo.

Habitualmente haríamos un UPDATE por cada seccion asignando el precio correcto a sus artículos.
UPDATE articulos
SET precio = precio * 1.05
WHERE seccion = 1;

UPDATE articulos
SET precio = precio * 1.08
WHERE seccion = 2;

UPDATE articulos
SET precio = precio * 1.10
WHERE seccion = 3;

 Dependiendo del número de filas que tenga la tabla de artículos, podemos conseguir un importante ahorro de tiempo realizando todas las operaciones en una única sentencia:
UPDATE articulos
SET precio =
CASE
WHEN seccion = 1 THEN precio*1.05
WHEN seccion = 2 THEN precio*1.08
WHEN seccion = 3 THEN precio*1.10
END

 Tenemos que tener en cuenta que al menos debe haber una condicion WHEN y que ésta puede ser múltiple, es decir, podemos condicionar la actualización a varias condiciones.
Por ejemplo:
UPDATE articulos
SET precio =
CASE
WHEN seccion = 1 AND precio >= 100 THEN precio*1.05
WHEN seccion = 1 AND precio <100 THEN precio*1.08
END

 Vemos que actualizamos los artículos de la seccion 1 pero con distinto factor según su precio actual.
Espero que os sirva de utilidad.

Hasta la próxima.













viernes, 13 de mayo de 2016

DECLARACION DE CURSORES EN INFORMIX CON LA CLAUSULA WITH HOLD. Declaring Informix cursors using the WITH HOLD clause.

Si declaramos un cursor en Informix que va a tratar muchas filas, puede ser que nos interese declarar una transacción por cada una de ellas. El problema viene cuando al hacer el COMMIT o ROLLBACK de la transacción, observamos que nuestro cursor queda automáticamente cerrado.

Para evitarlo debemos declarar el cursor con la clausula WITH HOLD. Esta clausula puede utilizarse tanto en r4gl como en un Stored Procedure.

En STORED PROCEDURES:
CREATE PROCEDURE 'informix'.procedureName()

    FOREACH WITH HOLD
          SELECT column1, column2 INTO var1, var2 FROM table1WHERE condicion

         BEGIN WORK;
         ---
         ---
         UPDATE table2 SET  column1 = column1 - var1 WHERE condicion;
         UDPATE table3 SET column1 = column1 + (column1 * var2 / 100)
                WHERE condicion;
         ---
         ---
         COMMIT WORK;

    END FOREACH;

END PROCEDURE;


 En R4GL:

DECLARE cursorName CURSOR WITH HOLD FOR
          SELECT column1, column2 FROM table1 WHERE condicion

FOREACH cursorName INTO var1, var2

         BEGIN WORK;
         ---
         ---
         UPDATE table2 SET  column1 = column1 - var1 WHERE condicion;
         UDPATE table3 SET column1 = column1 + (column1 * var2 / 100)  
                WHERE condicion;
         ---
         ---
         COMMIT WORK;

END FOREACH



Espero que os sea de utilidad.

lunes, 2 de mayo de 2016

SQL AVANZADO (II). USO DE LA FUNCION WEEKDAY EN SENTENCIAS SQL INFORMIX - Advanced Informix Sql (II). Using the weekday function in Sql

Si periodicamente os toca realizar un informe y para obtenerlo os basais en alguna query de esas maravillosas que guardais como si fueran de oro, es conveniente que incluyais la fecha del dia en que lo lanzais para poder hacer un seguimiento......

La fecha del dia puede incluirse con un simple TODAY, pero si queremos darle un formato mas 'amigable' podemos utilizar la funcion WEEKDAY.

Esta función nos devuelve el dia de la semana en que nos encontramos con un número cuyo significado va desde el 0 (Domingo) hasta el 6 (Sábado)

Si lo combinamos con la expresión CASE que vimos en otra entrada de este mismo blog, podremos obtener resultados interesantes:
SELECT CASE WEEKDAY(today)
    WHEN 0 THEN 'Domingo'
    WHEN 1 THEN 'Lunes'
    WHEN 2 THEN 'Martes'
    WHEN 3 THEN 'Miercoles'
    WHEN 4 THEN 'Jueves'
    WHEN 5 THEN 'Viernes'
    WHEN 6 THEN 'Sabado'
END || ', '|| day(today)|| ' de '||
CASE MONTH(today)
    WHEN 1 THEN 'Enero'
    WHEN 2 THEN 'Febrero'
    WHEN 3 THEN 'Marzo'
    WHEN 4 THEN 'Abril'
    WHEN 5 THEN 'Mayo'
    WHEN 6 THEN 'Junio'
    WHEN 7 THEN 'Julio'
    WHEN 8 THEN 'Agosto'
    WHEN 9 THEN 'Septiembre'
    WHEN 10 THEN 'Octubre'
    WHEN 11 THEN 'Noviembre'
    WHEN 12 THEN 'Diciembre'
END || ' de '|| YEAR(today) FECHA,
COUNT(*) PEDIDOS,
SUM(importe) IMPORTE
FROM pedidos


Obtendremos una salida como esta:


Estoy de acuerdo en que el ejemplo es un poco simple pero quiero que os quedeis con la idea de que con esta función combinada con la expresión CASE podeis obtener una salida interesante para una fecha.
Ni que decir tiene que igual que la he utilizado con TODAY podeis utilizarla con cualquier fecha incluyendo columnas de tipo DATE de vuestra base de datos.

Espero que os sirva de utilidad.
Hasta la próxima.