RubyLit - Ruby.del.litoral!
stores procedures triggers y funciones

Un trigger después de hacer un update.

La idea es la siguiente:

Se tienen dos tablas, una llamada ‘productos’ y la otra ‘pedidos’.

template1=# \d productos
         Tabla «public.productos»
     Columna     |  Tipo   | Modificadores 
-----------------+---------+---------------
 producto        | integer | not null
 stock           | integer | 
 stock_minimo    | integer | 
 stock_a_reponer | integer | 
template1=# \d pedidos
                              Tabla «public.pedidos»
     Columna     |  Tipo   |                    Modificadores                     
-----------------+---------+------------------------------------------------------
 id              | integer | not null default nextval('pedidos_id_seq'::regclass)
 producto        | integer | 
 stock_a_reponer | integer | 

La idea es que cuando se realice un update en la tabla pedidos que deje el campo ‘stock’ con un valor inferior al campo ‘stock_minimo’ se realice un insert en la tabla pedidos con el id del producto y la cantidad de productos a comprar, indicado por el campo ‘stock_a_reponer’.



El siguiente script crea las tablas el trigger y las funciones necesarias.

bajar el código fuente del trigger

Después de ejecutar el script debería comprobar que todo funciona correctamente ejecutando las siguiente instrucciones desde psql.

select * from productos;
select * from pedidos;
update productos set stock=9 where producto=1;
select * from productos;
select * from pedidos;

De esta manera se comprueba que en la tabla pedidos existe un registro que indica que hay que comprar 200 unidades del producto 1.

Compruebe que si ejecuta otra vez el comando update, por ejemplo:

update productos set stock=8 where producto=1;

Esta vez no se agregó otro registro en la tabla pedidos.

Esto es así porque el trigger comprueba si existe un pedido para ese producto.



require 'rubygems'
require 'pg'

drop1= "drop table if exists productos;" 
drop2= "drop table if exists pedidos;" 

tabla1 = "create table productos (
producto integer primary key,
stock integer,
stock_minimo integer,
stock_a_reponer integer);" 

tabla2 = "create table pedidos (
id serial primary key,
producto integer references productos (producto),
stock_a_reponer integer);" 

trigger = "CREATE TRIGGER productos_update  AFTER update
ON productos  FOR EACH ROW
EXECUTE PROCEDURE trig_prod_update();" 

funcion = "CREATE OR REPLACE FUNCTION trig_prod_update() RETURNS trigger as '
#warn \"Producto: \"  + new[\"producto\"];
#warn \"Stock a Reponer: \" + new[\"stock_a_reponer\"];

if new[\"stock\"].to_i < new[\"stock_minimo\"].to_i
    insertar = true
    PL.exec(\"select producto from pedidos where producto = \" + new[\"producto\"] )  do |x|
        insertar = false
    end
    if insertar
        PL.exec(\"insert into pedidos (producto, stock_a_reponer) values (\" + new[\"producto\"] + \",\" + new[\"stock_a_reponer\"] + \")\")
    end
end

return new
' LANGUAGE \"plruby\";" 

conn = PGconn.connect("127.0.0.1", 5432, '', '', "template1", "postgres", "pwdxyz")

res = conn.exec(drop2)
res = conn.exec(drop1)
res = conn.exec(tabla1)
res = conn.exec(tabla2)

#creamos la funcion que ejecuta el trigger
res = conn.exec(funcion)

#creamos el trigger
res = conn.exec(trigger)

#agregamos registros a la tabla productos
res = conn.exec("insert into productos values(1,100,10,200);")
res = conn.exec("insert into productos values(2,150,15,200);")
res = conn.exec("insert into productos values(3,200,20,200);")
res = conn.exec("insert into productos values(4,250,25,200);")
res = conn.exec("insert into productos values(5,300,30,200);")
res = conn.exec("insert into productos values(6,350,35,200);")
res = conn.exec("insert into productos values(7,400,40,200);")

Un trigger después de hacer un insert.

La idea es la siguiente:

Se tienen dos tablas, una llamada ‘pcuentas’ y la otra ‘registros’.

cada vez que se inserta un registro en la tabla registros se actualiza la tabla pcuentas.

template1=# \d pcuentas
       Tabla «public.pcuentas»
  Columna   |  Tipo   | Modificadores 
------------+---------+---------------
 cuenta     | integer | not null
 acumula_en | integer | 
 importe    | numeric | 
template1=# \d registros
                          Tabla «public.registros»
 Columna |  Tipo   |                     Modificadores                      
---------+---------+--------------------------------------------------------
 id      | integer | not null default nextval('registros_id_seq'::regclass)
 cuenta  | integer | 
 importe | numeric | 

para crear las tablas, el trigger la función ejecute el siguiente script

-- Solo muestro los mensajes de error.
set  client_min_messages = error;

-- Elimino las tablas creadas previamente. 
drop table if exists pcuentas; 
drop table if exists registros;

-- Creo la tabla pcuentas.
create table pcuentas (
cuenta integer primary key,
acumula_en integer,
importe numeric);

-- creo un indice sobre el campo acumula_en.
CREATE INDEX acumula_en_idx ON pcuentas (acumula_en);

-- Inserto unos cuantos registros.
insert into pcuentas values (1,null,0);
insert into pcuentas values (10,1,0);
insert into pcuentas values (11,1,0);
insert into pcuentas values (12,1,0);
insert into pcuentas values (100,10,0);
insert into pcuentas values (111,11,0);
insert into pcuentas values (122,12,0);

insert into pcuentas values (2,null,0);
insert into pcuentas values (20,2,0);
insert into pcuentas values (21,2,0);
insert into pcuentas values (22,2,0);
insert into pcuentas values (200,20,0);
insert into pcuentas values (211,21,0);
insert into pcuentas values (222,22,0);

-- Creo la tabla registros.
create table registros (
id serial primary key,
cuenta integer,
importe numeric);

set  client_min_messages = info;
-- Creo la funcion que será llamada por el trigger.
CREATE OR REPLACE FUNCTION trig_regis_insert() RETURNS trigger as '

warn "Cuenta: "  + new["cuenta"]
warn "Importe: "  + new["importe"]
add_importe = new["importe"]
tmp_cuenta = new["cuenta"]

#PL.exec("update pcuentas set importe = importe + " + add_importe + " where cuenta=" + new["cuenta"])

while !tmp_cuenta.nil? do
    warn "Acumula en: "  + tmp_cuenta
    PL.exec("update pcuentas set importe = importe + " + add_importe + " where cuenta=" + tmp_cuenta)
    PL.exec("select acumula_en from pcuentas where cuenta = " + tmp_cuenta ) do |x|
        #warn "Acumula en: " + x["acumula_en"]
        tmp_cuenta = x["acumula_en"]
    end
end

return new
' LANGUAGE "plruby";

-- Creo el trigger. Observe el orden: primero se crea la funcion luego el trigger.
CREATE TRIGGER registros_insert  AFTER insert
ON registros  FOR EACH ROW
EXECUTE PROCEDURE trig_regis_insert();

-- Restauro el nivel de mensajes
set  client_min_messages = info;

Puede ejecutar el script desde psql con el siguiente comando:

\i /var/lib/postgresql/pcuentas.sql;

Ahora inserte dos registros en la tabla ‘registros’

insert into registros (cuenta, importe) values (11, 10);
insert into registros (cuenta, importe) values (12, 10);
Compruebe el resultado.
template1=# select * from registros;
 id | cuenta | importe 
----+--------+---------
  1 |     11 |      10
  2 |     12 |      10
(2 filas)
template1=# select * from pcuentas;
 cuenta | acumula_en | importe 
--------+------------+---------
     10 |          1 |       0
    100 |         10 |       0
    111 |         11 |       0
    122 |         12 |       0
      2 |            |       0
     20 |          2 |       0
     21 |          2 |       0
     22 |          2 |       0
    200 |         20 |       0
    211 |         21 |       0
    222 |         22 |       0
     11 |          1 |      10
     12 |          1 |      10
      1 |            |      20
(14 filas)

pacquiao vs marquez Philippine Travel Travel Asia home ideas Fifa World Cup pacquiao vs marquez tickets donaire vs narvaez cotto vs margarito donaire vs narvaez tickets cotto vs margarito live streaming essay writing guide cotto vs margarito tickets st-pierre vs diaz st-pierre vs diaz tickets pacquiao vs marquez velasquez vs dos santos velasquez vs dos santos tickets