Quien soy? RSS feed Enviar por email Imprimir Parar este menu Ir arriba
Blogzote.com
Mexico, informatica, internet, musica y algo mas…

Trigger en tabla en Oracle

Algunas veces sucede que uno da por hecho que todo mundo sabe de lo que estamos hablando, refiriéndome a “todo mundo” por todo el equipo de trabajo de Oracle en mi actual proyecto, y mas hablando de cosas sencillas como un trigger a nivel de tabla, pero a veces resulta que no, hay cosas que uno sabe que otros no y viceversa.

Discutiendo la solución a un problema, algunos llegábamos a la conclusión de utilizar un trigger a nivel de tabla, unos estaban en contra y resulta que otros no sabían que existían, no hablare de eso, mas bien para los que no sepan, les hablare de cómo crearlos y para que sirven.

Un trigger a nivel de tabla sirve para que Oracle ejecute x o y cosa que deseemos, claro utilizando PL/SQL, al realizar algún DDL sobre una tabla (insert, delete, update) puede ser antes o después del DDL y se puede especificar una, dos o las tres acciones, incluso en la versión 11g ya se puede especificar el orden en que se desee se ejecuten los triggers, en caso de haber mas de uno sobre la misma tabla, se puede especificar si se desea la ejecución sobre cada registro procesado o que se realice por cada transacción y varias cosas mas.

La sintaxis es la siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE OR REPLACE TRIGGER <trigger_name>
[<ENABLE | DISABLE>]
<BEFORE | AFTER> <ACTION> [OR <ACTION> OR <ACTION>]
ON <table_name>
 
DECLARE
 <variable definitions>
BEGIN
  <trigger_code>
EXCEPTION
  <exception clauses>
END <trigger_name>;
/

Un ejemplito sencillo que ya había utilizado en un post anterior:

1
2
3
4
5
6
7
8
9
10
11
12
CREATE OR REPLACE TRIGGER tr_pk_employees 
  before INSERT ON employees
  FOR each ROW
DECLARE
 
BEGIN
 
  SELECT NVL(MAX(employee_id),0) + 1
    INTO :NEW.employee_id
    FROM employees;
 
END;

También podemos diferenciar la acción realizada dentro del trigger:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE OR REPLACE TRIGGER tr_pk_employees 
  before INSERT OR UPDATE OR DELETE
  ON employees
  FOR each ROW
DECLARE
 
BEGIN
 
  IF INSERTING THEN
    DBMS_OUTPUT.put_line('Inserting');
  ELSIF UPDATING THEN
    DBMS_OUTPUT.put_line('Updating');
  ELSIF DELETING THEN
    DBMS_OUTPUT.put_line('Deleting');
  END IF;
 
END;

El único detalle a destacar es que para referenciar las columnas de la tabla se utiliza el “:OLD” y el “:NEW”, por ejemplo en un “update”, “:old” tendrá el valor antes de la actualización y “:new” el valor después, en un “insert” no existe el valor “:old” y en un delete no existe el valor “:new”.

* 1 Comentario Email Imprimir

Case en Oracle

Hace algunos días, en mi actual proyecto, me pidieron que revisara una consulta, el problema era que sus tiempos se estaban elevando mucho, y considerando que con el tiempo la tabla iría creciendo aun mas, estamos hablando de millones de registros, era necesario aplicarle un poco de tunning al SQL.

No hablare de cómo optimizar una consulta en este momento, de planes de ejecución, uso de índices o de hints, etc. de lo que quería hablar era de algo mas censillo, del uso del “case” en una consulta.

En versiones anteriores a la 9i (creo que es esa versión la que incluye por primera vez el uso del “case”) no había otra forma de realizar una consulta condicionando el resultado de una columna mas que usando un “decode”, aunque funcionaba, no era una buena solución, no se podían condicionar rangos de valores, para cada valor posible se tenia que definir en el “decode”, resultaba mucho menos claro el código y varias cosas mas en contra.

Al revisar la consulta me doy cuenta que hace un uso extensivo de “decodes”, que aunque funcionan como deben, no es la mejor manera de hacerlo, aparte de que hace el SQL mas difícil de entender y hasta podría decir que también le están afectando a los tiempos de respuesta, no voy a incluir la consulta como tal, mejor dejo unos ejemplos de su uso para aquellos que todavía usan “decodes” en sus consultas.

Supongamos que tenemos una tabla con un campo llamado “TIPO”, los valores para este campo van desde la “A” a la “E”, a la vieja usanza, con un “decode” tendríamos algo así:

1
2
3
4
5
6
SELECT DECODE(TIPO,'A','TIPO A',
                   'B','TIPO B',
                   'C','TIPO C', 
                   'D','TIPO D',
                   'E','TIPO E', 'TIPO NO IDENTIFICADO') TIPO
  FROM TABLA

Ahora modificamos la consulta usando el case:

1
2
3
4
5
6
7
8
9
SELECT CASE TIPO 
          WHEN 'A' THEN 'TIPO A'
          WHEN 'B' THEN 'TIPO B'
          WHEN 'C' THEN 'TIPO C'
          WHEN 'D' THEN 'TIPO D'
          WHEN 'E' THEN 'TIPO E'
          ELSE 'TIPO NO IDENTIFICADO'
       END TIPO
  FROM TABLA

Hasta aquí pues a la vista no varia mucho, las dos las entiendo prácticamente igual, pero este es un ejemplo sencillo, ya verán como se dificultan las cosas cuando hablamos de millones de registros, aparte de que con el “case” ya estas haciendo las cosas como se deben hacer, bien hechas, ahora veamos las ventajas del case, ahora me piden simplemente identificar los valores conocidos y los no conocidos, con un “decode” no se podría tan fácilmente, igual se tendría que usar un “IN” o algo así, pero con el “case” es muy fácil:

1
2
3
4
5
6
SELECT CASE 
          WHEN TIPO BETWEEN 'A' AND 'E' THEN 
             'TIPO IDENTIFICADO'
          ELSE 'TIPO NO IDENTIFICADO'
       END TIPO
  FROM TABLA

Ahora resulta que me piden identificar los valores “A” y “E” para procesarlos de una manera, los valores “B”, “C” y “D” para procesarlos de otra y todos los demás se quedan sin procesar:

1
2
3
4
5
6
7
8
SELECT CASE 
          WHEN TIPO IN ('A','E') THEN 
             'PROCESO A y E'
          WHEN TIPO IN ('B','C','D') THEN 
             'PROCESO B, C y D'
          ELSE 'NO PROCESO'
       END TIPO
  FROM TABLA
Sin comentarios Email Imprimir

El paraíso mexicano

Y no me refiero a Cancún, Huatulco o alguna playa paradisíaca mexicana, me refiero al paraíso en el que se encuentran los bancos en México (Así como muchas otras empresas verdad Slim?), desde hace muchos años que manejo cuentas bancarias y una o dos tarjetas de crédito y siempre me he quejado de las exageradas comisiones que cobran.

Ya hace algunos meses hablaba de mi comparación entre los bancos que conocía en ese entonces (banamex, bancomer y hsbc) ahora conozco otros mas como santander, banorte y scotiabank y sigo pensando que todos son una porquería en mayor o menor grado, pero el que de plano se las mata a todos es HSBC, me cobran comisión por no mantener un saldo mínimo, aparte de la comisión por el solo hecho de tener la cuenta, me cobran comisión por retiro en ventanilla, por retiro en cajeros de esos que están en centros comerciales y no en sucursal, y segurito cobran mas comisiones pero no he usado ya mas servicios de este banco.

Todo esto sale a colación por una nota que leí al respecto:

Los coordinadores del PAN y el PRD en el Senado, Gustavo Madero y Carlos Navarrete, respectivamente, coincidieron con el empresario Carlos Slim en la urgencia de que los bancos disminuyan o establezcan un tope en las tasas de interés en tarjetas de crédito y créditos hipotecarios, y advirtieron que si a partir de enero la situación continúa van a legislar a fondo.

(…)

En entrevista, el legislador del Partido Acción Nacional (PAN) indicó que, por ejemplo, los intereses que cobra Scotiabank en México son de 76 por ciento, mientras que en Canadá son de 18 por ciento.

El secretario de la Comisión de Energía del Senado precisó que BBVA Bancomer cobra hasta 80 por ciento contra 25 por ciento que aplica en España, donde está su matriz, y en Banamex el costo anual es de 80 por ciento cuando en Estados Unidos, país de origen del Grupo Citigroup, es de 12 por ciento.

(…)

Noticia completa

Todo empezó a partir de que Slim hablo de las exageradas tasas de interés que cobran los bancos, ¿pero si el tiene un montón de lana?, no creo que le afecte una comisión de 40 pesos mensuales mas IVA (mas todas las demás) como de la que me quejo yo con HSBC, igual también por ahí ve afectados sus intereses, por que no creo que hable por la ciudadanía.

A partir de ahí salieron nuestros politicuchos a amenazar, en lugar de a trabajar en lo que deberían, ahora resulta que son los bancos los que “deberían” establecer un tope o reducir sus tarifas, jajaja, si ya vimos que a esos ratas les das un huevo y te agarran la p…, y es que cobrar el 80% de interés no tiene otras palabras mas que “robo”, y eso que no cuentan en esa tasa las comisiones, el interés de los intereses, el IVA, etc. Y en el supuesto caso que sus “amenazas” funcionen, en cuanto tiempo tendremos de nuevo esas o mas altas tasas?

Al final acabas pagando más del doble de lo que te prestan, y no conformes tienes que lidiar con sus pésimos servicios, no por nada tres bancos están en el Top 10 de las empresas mas apestosas, al fin ya saben que no pasa nada, saben que ahí esta la condusef para dizque “defender” a la gente, saben que como muchas otras instituciones, la condusef es solo la pantalla para que la gente común y corriente calme su frustración e incapacidad de hacer algo contra ellos.

Sin comentarios Email Imprimir