Ver Mensaje Individual
  #4  
Antiguo 26-06-2014
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Reputación: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Yo utilizo IDs para cada registro de la tabla y luego otros campos para los números de orden, pedido, factura, etc.
El ID es un campo obtenido de un generador y el número del documento se calcula en los triggers.
Todo lo hecho en un trigger está dentro de una misma transacción, por lo que si no hay errores al insertar/modificar, la base de datos se ha encargado de que no haya duplicados.

Yo trabajo con Firebird. Esta base tiene generadores que devuelven el número siguiente del actual.
En los eventos BeforePost es donde obtengo un número para mi ID y se lo asigno al parámetro del dataset. Este ID es imposible que se duplique, por lo solo queda esperar a que el SQL se complete y refrescar los datos que sean necesarios (NRO_DOCUMENTO, TOTALES, etc.)

Código Delphi [-]
function TDMMain.DameGenerador(NomGen: string): integer;
var
  Q : THYFIBQuery;
begin
  Result := 0;
  if (Trim(NomGen) > '') then
  begin
     Q := THYFIBQuery.Create(nil);
     try
        with Q do
        begin
           Close;
           DataBase := Self.DataBase;
           SQL.Text := 'SELECT GEN_ID(' + NomGen + ',1) FROM RDB$DATABASE';
           ExecQuery;
           Result := Fields[0].AsInteger;
           Close;
           FreeHandle;
        end;
     finally
        FreeAndNil(Q);
     end;
  end;
end;

procedure TDMFacturas.QMCabeceraBeforePost(DataSet: TDataSet);
var
  existe : smallint;
begin
  // Solo asigno ID si estoy insertando
  if (DataSet.State = dsInsert) then
     DataSet.FieldByName('ID_CAB_FACTURA_CLI').AsInteger := DMMain.DameGenerador('GEN_CAB_FACTURA_CLI');
  [...]
end;

El trigger sería algo así:
Código SQL [-]
créate trigger CAB_FACTURA_CLI_BI0 for FACTURA before insert 0
as
begin
    /* Calculo el ID si vino vacio */
    if ((new.ID_CAB_FACTURA_CLI = 0) or (new.ID_CAB_FACTURA_CLI is null)) then
        newID_CAB_FACTURA_CLI := GEN_ID(GEN_CAB_FACTURA_CLI, 1);

    /* Calculo el siguiente numero de factura */
    select max(numero) from CAB_FACTURA_CLI
    where
    empresa = new.empresa and
    ejercicio = new.ejercicio and
    serie = new.serie
    into new.numero;
  
    /* Si es la primera factura no me habrá devuelto nada util */
    if ((numero =0) or (new.numero is null)) then
        new.numero = 1;

    [...]
end

Última edición por duilioisola fecha: 26-06-2014 a las 21:55:17.
Responder Con Cita