Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   triggers sobre vistas (https://www.clubdelphi.com/foros/showthread.php?t=14331)

marti 16-09-2004 18:54:59

triggers sobre vistas
 
Deseo hacer un trigger sobre una vista, de forma tal que realice un cálculo sobre algún campo de la vista.

La vista luce asi:

Código SQL [-]
CREATE VIEW ITEM_INVENTARIO_INFO (
  ID_ITEM, 
  ID_BODEGA, 
  CANTIDAD, 
  COSTO, 
  TOTAL_COSTO, 
  PRIORIDAD
) AS
SELECT CD.ID_ITEM,CD.ID_BODEGA,CD.CANTIDAD,25.0,0.0,5
FROM REMISION C INNER JOIN REMISION_DET CD ON (C.ID_EMPRESA=CD.ID_EMPRESA AND C.ID_SUCURSAL=CD.ID_SUCURSAL AND C.ID_TIPO_DOC = CD.ID_TIPO_DOC AND C.NUMERO = CD.NUMERO)
UNION
SELECT CD.ID_ITEM,CD.ID_BODEGA,CD.CANTIDAD,25.0,0.0,5
FROM FACTURA C INNER JOIN FACTURA_DET CD ON (C.ID_EMPRESA=CD.ID_EMPRESA AND C.ID_SUCURSAL=CD.ID_SUCURSAL AND C.ID_TIPO_DOC = CD.ID_TIPO_DOC AND C.NUMERO = CD.NUMERO)
;

y el trigger luce asi:

Código SQL [-]
CREATE TRIGGER TRIG_ITEM_INVENTARIO_INFO FOR ITEM_INVENTARIO_INFO 
ACTIVE AFTER UPDATE POSITION 0
as
BEGIN
  NEW.TOTAL_COSTO = NEW.CANTIDAD* NEW.COSTO;
END
 ^

El motor de la base de datos no genera ningún tipo de error al crear el trigger sobre la vista pero no hace lo que deseo que haga.

La vista me devuelve los siguientes registros

Código:


ID_ITEM  ID_BODEGA CANTIDAD COSTO TOTAL_COSTO  PRIORIDAD       
0001          01                        20                  25                          0                        5       
0001          01                        50                  25                          0                        5       
0002          01                        10                  25                          0                        5       
0002          01                        20                  25                          0                        5       
0003          01                          2                  25                          0                        5       
0003          01                        100                  25                          0                        5

El campo Total deberia tener un valor mayor a cero (cantidad*costo)

Es posible realizar este tipo de actualizaciones con Firebird?

Gracias por su colaboración
:confused:

guillotmarc 17-09-2004 20:58:46

Hola.

¿ No seria mucho más sencillo incorporar ese calculo en la misma consulta, sin necesidad de ningún trigger ?

Código SQL [-]
CREATE VIEW ITEM_INVENTARIO_INFO (
  ID_ITEM, 
  ID_BODEGA, 
  CANTIDAD, 
  COSTO, 
  TOTAL_COSTO, 
  PRIORIDAD
) AS
SELECT CD.ID_ITEM,CD.ID_BODEGA,CD.CANTIDAD,25.0,CD.CANTIDAD*25.0,5
FROM REMISION C INNER JOIN REMISION_DET CD ON (C.ID_EMPRESA=CD.ID_EMPRESA AND C.ID_SUCURSAL=CD.ID_SUCURSAL AND C.ID_TIPO_DOC = CD.ID_TIPO_DOC AND C.NUMERO = CD.NUMERO)
UNION
SELECT CD.ID_ITEM,CD.ID_BODEGA,CD.CANTIDAD,25.0,CD.CANTIDAD*25.0,5
FROM FACTURA C INNER JOIN FACTURA_DET CD ON (C.ID_EMPRESA=CD.ID_EMPRESA AND C.ID_SUCURSAL=CD.ID_SUCURSAL AND C.ID_TIPO_DOC = CD.ID_TIPO_DOC AND C.NUMERO = CD.NUMERO)
;

NOTA : Desconozco si los triggers sobre vistas, se pueden usar de la forma que deseas. Aunque no lo veo nada claro. Tal como lo tengo entendido solo són para poder hacer modificables las vistas, es decir que si modificas un registro de la vista, salte el trigger para que tu código pueda indicar que tablas hay que modificar realmente.

Saludos.

marti 20-09-2004 22:24:20

Gracias por responder guillotmarc, creo que no explique lo suficiente.

El problema que tengo que resolver es el siguiente:
Estoy desarrollando una aplicación que maneja el control de inventarios de una empresa, resulta que el sistema debe costear las existencias de inventario utilizando el método del promedio ponderado.
Básicamente, las transacciones son entradas y salidas del almacén donde está la mercancia, para esto he tratado de resolver el problema usando una
tabla para las facturas de ventas (Salidas del almacén) y devoluciones de facturas de venta (Entrada del almacén)
y otra tabla para los documentos que tiene que ver con las compras de mencancía, estos son Entradas de almacén (Entradas del almacén)
y Devoluciones de compra (Salidas del almacén).
Para realizar el cálculo del costo promedio los transacciones se realizan así:
Código:


Fecha          detalle  |Entradas        |Salidas                          |saldos                  |costo unit
                                                        cant|costo        cant|costo          cant| costo 
-----------------------------------------------------------------------
20/10/03 "compra"          10 150,0000        0                  0                10  150,000 15,000
 
21/10/03 "compra"          40  600,000        0                  0            50  750,000 15,000
 
22/10/03 "venta  "          0                        0  30  450,000                20  300,000 15,000
 
23/10/03 "dev.comp" (5)  (75,000)        0                  0                15  225,000 15,000
 
22/10/03 "dev.venta"  0                        0  (2) (30,000)                17  255,000 15,000

1. En entradas: se registra la cantidad y el costo total de la compra o devolución de compra.

2. En salidas: se registra la cantidad de mercancia vendida; y en la columna del costo el resultado de multiplicar la cantidad por el costo unitario del renglón anterior.

3. En saldos: para obtener los valores de esta columna, a los valores del saldo anterior se le adicionan las entradas o se les disminuyen las salidas.

4. Costo unitario: para obtener el costo unitario se toma la columna de saldo anterior y se divide el costo total entre la cantidad total de cada renglón.
El costo total varia siempre que se compra mercancía a precio diferente; cuando se registra la salida se mantiene el último costo unitario.

Las estructuras de las tablas de ventas y compras lucen más o menos así:

Código SQL [-]
 
VENTA_DET
-------------
ID_ITEM
CANTIDAD
COSTO
TOTAL 
 
COMPRA_DET
------------
ID_ITEM
CANTIDAD
COSTO
TOTAL

Lo que desea realizar con la vista es hacer el cálculo del costo promedio de forma automática,
debido a que si por algún motivo uno de los registros correspondiente a entradas es retirado no tenga que recorrer toda la tabla para recalcular el costo unitario y mucho menos el saldo.

Código SQL [-]
CREATE VIEW ITEM_INVENTARIO_INFO 
( 
 FECHA  ID_ITEM,  
CANTIDAD_ENTRADA,  
COSTO_ENTRADA,   
CANTIDAD_SALIDA,   
COSTO_SALIDA,   
CANTIDAD_SALDO,  
COSTO_SALDO,  
COSTO_UNITARIO) AS 
 
SELECT C.FECHA,CD.ID_ITEM,CD.CANTIDAD,CD.COSTO,0.0,0.0,0.0,0.0,0.0
FROM COMPRA C INNER JOIN COMPRA_DET CD ON
(C.ID_EMPRESA=CD.ID_EMPRESA AND C.ID_SUCURSAL=CD.ID_SUCURSAL AND 
C.ID_TIPO_DOC = CD.ID_TIPO_DOC AND C.NUMERO = CD.NUMERO)
UNION
SELECT C.FECHA,CD.ID_ITEM,0.0,0.0,CD.CANTIDAD,CD.COSTO,0.0,0.0,0.0
FROM VENTA C INNER JOIN VENTA_DET CD ON 
(C.ID_EMPRESA=CD.ID_EMPRESA AND C.ID_SUCURSAL=CD.ID_SUCURSAL AND 
C.ID_TIPO_DOC = CD.ID_TIPO_DOC AND C.NUMERO = CD.NUMERO);

Hasta ahora no conozco una forma de hacer una consulta SQL que me permita obtener el valor del costo unitario.
Por esta razon envio algunos campo de la vista en cero y posteriormente con el trigger deseaba poder modificar dichos campos.

Si no es posible hacer esto de que forma podría obtener este resultado?

Cómo hago para que me queden bien organizados los valores que tiene forma de tabla como en el ejemplo de arriba, la verdad intenté de varias formas y no logre que quedará organizado.

Saludos

guillotmarc 21-09-2004 11:56:48

Hola.

Con el trigger no puedes hacerlo, puesto que no están diseñados para este uso.

Puedes utilizar un procedimiento almacenado.

Ejplo. sencillo de procedimiento almacenado que devuelve un conjunto de datos :

Código SQL [-]
CREATE PROCEDURE "CLIENTES_Lista" 
RETURNS (
    ID INTEGER,
    NOMBRE VARCHAR(50),
    APELLIDOS VARCHAR(50))
AS
begin
  for select ID, NOMBRE, APELLIDOS
      from CLIENTES
      into :ID, :NOMBRE, :APELLIDOS
  do begin
    suspend;
  end
end

NOTA: Antes del suspend puedes hacer todos los cálculos necesarios sobre el coste unitario.

Para recoger los datos del procedimiento almacenado puedes hacer algo como :

select * from "CLIENTES_Lista"

Saludos.

marti 21-09-2004 16:41:17

Hola

Trataré de solicionar el problemas de acuerdo con tus sugerencias.

Gracias por tu valiosa colaboración. :D


La franja horaria es GMT +2. Ahora son las 05:01:38.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi