Re: GENERAR CODIGOS DE VENTA SIN DUPLICADOS EN POSTGRESQL ( ESTARA BIEN ? )

From: Alejandro Carrillo <fasterzip(at)yahoo(dot)es>
To: "pgsql-es-ayuda(at)postgresql(dot)org" <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: GENERAR CODIGOS DE VENTA SIN DUPLICADOS EN POSTGRESQL ( ESTARA BIEN ? )
Date: 2011-10-25 02:43:43
Message-ID: 1319510623.71762.YahooMailNeo@web27408.mail.ukl.yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Esta respuesta es similar a otra que hicieron una vez y yo la respondi:
1) Puedes usar un trigger before insert or update que le cree el proximo usando usa secuencia (no hay necesidad de usar esa tabla TGeneradorCodigoVentas)

2) Si puede ser autoincremental el cod_venta usa un tipo serial o bigserial a la hora de declarar la tabla.
* En ambos casos, seria buena idea declarar una unique constraint

________________________________
De: cesar salcedo <plicanhpc(at)gmail(dot)com>
Para: pgsql-es-ayuda(at)postgresql(dot)org
Enviado: lunes 24 de octubre de 2011 19:07
Asunto: [pgsql-es-ayuda] GENERAR CODIGOS DE VENTA SIN DUPLICADOS EN POSTGRESQL ( ESTARA BIEN ? )

Hola como están
espero que me puedan ayudar con una duda que me está rondando la cabeza desde
hace ya varios días , bueno vamos al asunto ,tengo estas tablas :
 
CREATE TABLE
"TGeneradorCodigoVentas"
(
Ultimo_CodVenta              CHAR(14) NOT NULL , -- 'DVEN-000000001'
PRIMARY KEY
(Ultimo_CodVenta)
);
 
CREATE TABLE
"TDoc_Venta" -- representa
los datos de cabecera del documento de venta
(
Cod_Venta                        CHAR(14)
NOT NULL,   -- 'DVEN-000000001'
TipoDocumento              CHAR(4) NOT NULL
CHECK(TipoDocumento IN ('PROF','BOLE','FACT')),
Serie_Documento          CHAR(3) NOT NULL,--002
Cod_Documento             VARCHAR(7)
NOT NULL,-- 0000265
Id_Tienda                           CHAR(8) NOT NULL
Id_Cliente                          CHAR(13)  NOT NULL,
Id_Usuario                         CHAR(8)
NOT NULL,
Fecha_Venta                    TIMESTAMP NOT NULL,
.....etc
PRIMARY KEY
(Cod_Venta,TipoDocumento,Serie_Documento,Cod_Documento,Id_Tienda),
FOREIGN KEY (Id_Tienda)
REFERENCES  "TTienda",
.....
);
 
el asunto es
que deseo generar los códigos de  venta y
que no se me dupliquen para otros usuarios ya que en cada tienda existen 8
ventanillas de cobro o cajeros , sin nombrar que la empresa posee varias
sucursales con las mismas características(varios cajeros)
mi código es
:
 
CREATE OR REPLACE FUNCTION Sfu_GenerarNuevoCodigoDctoVenta()
RETURNS TEXT AS $$
DECLARE
 NuevoCodVenta   CHAR(14); ParteNumCodActual  INT;
BEGIN
  SELECT (SubString(Ultimo_CodVenta FROM 6 FOR 14) :: INT) INTO
ParteNumCodActual FROM "TGeneradorCodigoVentas";
  --Luego generamos el nuevo código de venta
  IF ParteNumCodActual  IS  NULL  THEN -- Quiere decir que la tabla esta vacía
     NuevoCodVenta  :=  'DVEN-'  || LPAD(1::TEXT,9,'0');
  ELSE -- La tabla ya contiene datos
    NuevoCodVenta  :=  'DVEN-'  || LPAD((ParteNumCodActual +1)::TEXT,9,'0');
  END IF;
 RETURN NuevoCodVenta;
END $$ LANGUAGE 'plpgsql'; 
 
CREATE OR REPLACE FUNCTION Sfu_InsertNuevaVenta ( ....)
RETURNS TEXT  AS  $$
DECLARE
  Var_Mensaje                  TEXT; 
  IN_CodVenta                  CHAR(14);
.....
BEGIN
                --Obtenemos el siguiente código
para el documento de venta
                IN_CodVenta  :=  Sfu_GenerarNuevoCodigoDctoVenta();
                UPDATE
"TGeneradorCodigoVentas" SET Ultimo_CodVenta = IN_CodVenta ;
....
                --Finalmente Insertamos los
Datos de la Venta
                INSERT INTO
"TDoc_Venta" (Cod_Venta, , ,.....)
               VALUES (IN_CodVenta, ,....)
.....
   Var_Mensaje:='LOS DATOS DE LA VENTA SE
GRABARON CORRECTAMENTE' ;
   RETURN Var_Mensaje;
END $$  LANGUAGE 'plpgsql';
 
LA DUDA está en que en el modulo de
ventas como puedo garantizar que este código que estoy generando
('DVEN-00000000N') con la función anterior no se repita para otras ventanillas
de cobro ,ósea si el cajero 1 está realizando una venta y al MISMO TIEMPO otros cajeros de la misma
tienda están registrando otras ventas ,que debería hacer para garantizar que el
código sea diferente para todos ellos ósea ('DVEN-00000000N' ,
'DVEN-00000000(N+1)', para el otro cajero ,'DVEN-000000009(N+2)' para el sigte
y así )
 
Tendría que
usar   LOCK TABLE  en algún lugar  , tendría que usar TRANSACCIONES SERIALIZABLES  (esperar a que un cajero termine de realizar
una venta para recién generar otro código ),o la misma función (Sfu_InsertNuevaVenta) por tener una transacción
implícita ya es suficiente , o que tipo de bloqueos usa postgresl 9.0 será  READ
COMMITTED , o  SERIALIZABLE
vamos muchachos por favor seria chévere
que opinen o si desean ayudarme en privado :
plicanhpc(at)gmail(dot)com gracias de
antemano he , un saludo desde Perú .
 
Ha y
porque cojo los códigos de otra tabla y no hago algo así como :
 
  SELECT  MAX (SubString(Ultimo_CodVenta FROM 6 FOR 14) :: INT) INTO
ParteNumCodActual FROM "TGeneradorCodigoVentas"
 
NuevoCodVenta
:= 'DVEN-' || LPAD((ParteNumCodActual +1)::TEXT,9,'0');
 
 
Pues porque
la tabla de Ventas crece demasiado rápido con tantas ventas que se hacen por día
y hacer un MAX  es muy costoso

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Alvaro Herrera 2011-10-25 02:58:19 Re: GENERAR CODIGOS DE VENTA SIN DUPLICADOS EN POSTGRESQL ( ESTARA BIEN ? )
Previous Message Alvaro Herrera 2011-10-25 01:09:46 Re: GENERAR CODIGOS DE VENTA SIN DUPLICADOS EN POSTGRESQL ( ESTARA BIEN ? )