Ir al contenido



Foto

Enviar array por DataSnap


  • Por favor identifícate para responder
5 respuestas en este tema

#1 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 433 mensajes

Escrito 21 enero 2015 - 02:30

Hola amigos, hasta el momento tenia en mi servidor datasnap algunas funciones que insertaban en tablas madres y en tabla relacion, como:

se insertaba un telefono y en telcli(relaciona telefonos y clientes) los ids. entonces llamaba a una funcion que ejecutaba los 2 querys en una transaccion.

Pero ahora quiero insertar un presupuesto y en presuprodu(varios a varios de productos con presupuestos) el id del presupuesto insertado y todos los ids productos que contiene.

Pense realizar 2 procedimientos separados pero, deberia estar en el mismo para realizar todos los inserts en la misma transaccion, entonces se me ocurre enviar un array de idproductos, e iterar de 1 a la cantidad de partes del array insertando.

Otra pregunta: es posible crear una transaccion global en la unidad del servidor? asi podria insretar todo en un solo procedure?
  • 0

#2 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 520 mensajes
  • LocationCali, Colombia

Escrito 21 enero 2015 - 08:22

Hola

Creo que tu ya tenías un procedimiento donde pasabas un array de datasets, es exactamente lo mismo,  pasas el array de tatasets en el orden en el cual se deben insertar, entonces antes de recorrer el array inicias la transacción,  "aplicas" los datasets y cierras la transacción.

Creo que es eso si te entendí bien.

Saludos.
  • 0

#3 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 433 mensajes

Escrito 21 enero 2015 - 03:08

Es igual que al guardar datos del detalle de la factura, para cada producot debes insertar el idproducto en la tabla que contiene el idticket y el idproducto es decir la relacion varios a varios, igual pasaria con un presupuesto. entonces al llamar un metodo en datasnap le pasamos variables, podria llamar iterando a una funcion que inserte estos resgistros:

Por cada producto en el dataset del lado del cliente insertarproducto por ej, pero el caso es que la cabecera del ticket se inserta una vez nomas, entonces serian 2 procedimientos separados.

si necesitan mas detalle se los doy.
  • 0

#4 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 520 mensajes
  • LocationCali, Colombia

Escrito 21 enero 2015 - 04:58

Hola, la verdad no he entendido bien,  si puedes mostrar el modelo de datos sería más fácil.


  • 0

#5 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 433 mensajes

Escrito 22 enero 2015 - 01:34

Para guardar el ticket tengo:
Los datos generales


delphi
  1. create table ticket(
  2. idticket int not null auto_increment primary key,
  3. numero integer,
  4. importe decimal(10,2),
  5. fechae date,
  6. horae time,
  7. idsucursal int,
  8. foreign key (idsucursal) references sucursal(idsucursal) on delete no action
  9. );



Esta es el producto:



delphi
  1. create table producto(
  2. idproducto int not null auto_increment primary key,
  3. idcategoria int,
  4. idsubcategoria int,
  5. idmarca int,
  6. precio decimal(10,2),
  7. iva decimal(10,2),
  8. pedir boolean,
  9. nombre varchar(100),
  10. foreign key (idsubcategoria) references subcategoria(idsubcategoria) on delete no action,
  11. foreign key (idcategoria) references categoria(idcategoria) on delete no action,
  12. foreign key (idmarca) references marca(idmarca) on delete no action
  13. );



Y la relacion:



delphi
  1. create table venta(
  2. idticket int,
  3. idproducto int,
  4. cantidad decimal(10,2),
  5. foreign key (idticket) references ticket(idticket),
  6. foreign key (idproducto) references producto(idproducto)
  7. );



Entonces un ticket tiene sus datos generales y por cada producto del detalle se debe hacer un insert en venta. ¿Como seria una funcion DataSnap? Para el presupuesto hice:



delphi
  1. procedure TServerMethods1.nuevopresupuesto(idc,ide,ids,idp:integer;fechac,
  2. fechai,fechaf:string;preciou:Double);
  3. var
  4. tr:TDBXTransaction;
  5. begin
  6.   if (SUCURSAL.InTransaction) then
  7.     raise Exception.Create('Hay una transacción pendiente');
  8.     SUCURSAL.Open;
  9.       try
  10.           try
  11.             tr:=SUCURSAL.BeginTransaction();
  12.             with qipresu do
  13.               begin
  14.                 Close;
  15.                 ParamByName('idc').AsInteger:=idc;
  16.                 ParamByName('ide').AsInteger:=ide;
  17.                 ParamByName('ids').AsInteger:=ids;
  18.  
  19.                 ParamByName('fechac').AsString:=fechac;
  20.                 ParamByName('fechai').AsString:=fechai;
  21.                 ParamByName('fechaf').AsString:=fechaf;
  22.                 ParamByName('preciou').AsFloat:=preciou;
  23.  
  24.                 ExecSQL();
  25.               end;
  26.           with qipp do
  27.             begin
  28.               Close;
  29.               ParamByName('idp').AsInteger:=idp;
  30.  
  31.             end;
  32.         SUCURSAL.CommitFreeAndNil(tr);
  33.  
  34.       except
  35.         SUCURSAL.RollbackFreeAndNil(tr);
  36.         end;
  37.       finally
  38.       SUCURSAL.Close;
  39.       end;
  40. end;


Si llamo a este procedimiento por cada producto me insertaria el presupuesto varias veces. Entonces necesito pasar como parametro un array de idproducto y otro de precios.

De lo contrario tengo que separar en 2 procedures, uno para el presupuesto datos generales, y otro para iterar enviando de a un idproducto.
  • 0

#6 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 433 mensajes

Escrito 24 enero 2015 - 04:38

Hice lo siguiente:



delphi
  1. procedure TServerMethods1.nuevopresupuesto(idc,ide,ids:integer;fechac,
  2. fechai,fechaf:string);
  3.  
  4. var
  5. tr:TDBXTransaction;
  6. begin
  7.   if (SUCURSAL.InTransaction) then
  8.     raise Exception.Create('Hay una transacción pendiente');
  9.     SUCURSAL.Open;
  10.       try
  11.           try
  12.             tr:=SUCURSAL.BeginTransaction();
  13.             with qipresu do
  14.               begin
  15.                 Close;
  16.                 ParamByName('idc').AsInteger:=idc;
  17.                 ParamByName('ide').AsInteger:=ide;
  18.                 ParamByName('ids').AsInteger:=ids;
  19.  
  20.                 ParamByName('fechac').AsString:=fechac;
  21.                 ParamByName('fechai').AsString:=fechai;
  22.                 ParamByName('fechaf').AsString:=fechaf;
  23.  
  24.  
  25.                 ExecSQL();
  26.               end;
  27.  
  28.  
  29.  
  30.  
  31.         SUCURSAL.CommitFreeAndNil(tr);
  32.  
  33.       except
  34.         SUCURSAL.RollbackFreeAndNil(tr);
  35.         end;
  36.       finally
  37.       SUCURSAL.Close;
  38.       end;
  39. end;
  40. procedure TServerMethods1.nuevodetallepresupuesto(idprodu:integer;cantidad,preciou:Double);
  41. var
  42. tr:TDBXTransaction;
  43. begin
  44.       if (SUCURSAL.InTransaction) then
  45.     raise Exception.Create('Hay una transacción pendiente');
  46.     SUCURSAL.Open;
  47.       try
  48.           try
  49.             tr:=SUCURSAL.BeginTransaction();
  50.  
  51.               begin
  52.                 with qipp do
  53.                   begin
  54.                     Close;
  55.                     ParamByName('idp').AsInteger:=qupresu.ExecSQL();
  56.                     ParamByName('idprodu').AsInteger:=idprodu;
  57.                     ParamByName('preciou').AsFloat:=preciou;
  58.                     ParamByName('cantidad').AsFloat:=cantidad;
  59.                     ExecSQL();
  60.                   end;
  61.  
  62.         SUCURSAL.CommitFreeAndNil(tr);
  63.               end;
  64.  
  65.       except
  66.         SUCURSAL.RollbackFreeAndNil(tr);
  67.         end;
  68.       finally
  69.       SUCURSAL.Close;
  70.       end;
  71. end;



el primer metodo inserta la cabecera del presupuesto, empleado,sucursal,cliente,y fechas, y el segundo el detalle, tengo entonces el cliente asi:



delphi
  1. a:=TServerMethods1Client.Create(ClientModule1.SQLConnection1.DBXConnection);
  2.   idc:=1;
  3.               ide:=1;
  4.               ids:=1;
  5.               fechac:=Eemititdo.Text;
  6.               fechai:=Eemititdo.Text;
  7.               fechaf:=Evalido.Text;
  8.  
  9.               a.nuevopresupuesto(idc,ide,ids,fechac,fechai,fechaf);
  10.   l:=ClientModule1.cdspresu.RecordCount;
  11.         x:=0;
  12.         b:=TServerMethods1Client.Create(ClientModule1.SQLConnection1.DBXConnection);
  13.       while x < l do
  14.  
  15.             begin
  16.               inc(x);
  17.               cantidad:=ClientModule1.cdspresucantidad.AsFloat;
  18.               preciou:=ClientModule1.cdspresuprecio.AsFloat;
  19.               idprodu:=ClientModule1.cdspresuidproducto.AsInteger;
  20.               b.nuevodetallepresupuesto(idprodu,cantidad,preciou);
  21.  
  22.             end;
  23.  
  24.  
  25. end;



Y no me inserta la cabecera del presupuesto, solo el detalle.

Lo que quise hacer fue crear los procedimientos separados, entonces una vez inserto el detalle y otra vez itero sobre la cantidad de articulos insertandolos de a uno.

Me parece que deberia crear 2 transacciones distintas y que si falla la del segundo procedimiento hacer rollback sobre la primera, entonces solo hacer commit sobre la primera despues de la segunda.
  • 0