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?
Enviar array por DataSnap
Comenzado por
giulichajari
, ene 21 2015 02:30
5 respuestas en este tema
#1
Escrito 21 enero 2015 - 02:30
#2
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.
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.
#3
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.
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.
#4
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.
#5
Escrito 22 enero 2015 - 01:34
Para guardar el ticket tengo:
Los datos generales
Esta es el producto:
Y la relacion:
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:
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.
Los datos generales
delphi
create table ticket( idticket int not null auto_increment primary key, numero integer, importe decimal(10,2), fechae date, horae time, idsucursal int, foreign key (idsucursal) references sucursal(idsucursal) on delete no action );
Esta es el producto:
delphi
create table producto( idproducto int not null auto_increment primary key, idcategoria int, idsubcategoria int, idmarca int, precio decimal(10,2), iva decimal(10,2), pedir boolean, nombre varchar(100), foreign key (idsubcategoria) references subcategoria(idsubcategoria) on delete no action, foreign key (idcategoria) references categoria(idcategoria) on delete no action, foreign key (idmarca) references marca(idmarca) on delete no action );
Y la relacion:
delphi
create table venta( idticket int, idproducto int, cantidad decimal(10,2), foreign key (idticket) references ticket(idticket), foreign key (idproducto) references producto(idproducto) );
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
procedure TServerMethods1.nuevopresupuesto(idc,ide,ids,idp:integer;fechac, fechai,fechaf:string;preciou:Double); var tr:TDBXTransaction; begin if (SUCURSAL.InTransaction) then raise Exception.Create('Hay una transacción pendiente'); SUCURSAL.Open; try try tr:=SUCURSAL.BeginTransaction(); with qipresu do begin Close; ParamByName('idc').AsInteger:=idc; ParamByName('ide').AsInteger:=ide; ParamByName('ids').AsInteger:=ids; ParamByName('fechac').AsString:=fechac; ParamByName('fechai').AsString:=fechai; ParamByName('fechaf').AsString:=fechaf; ParamByName('preciou').AsFloat:=preciou; ExecSQL(); end; with qipp do begin Close; ParamByName('idp').AsInteger:=idp; end; SUCURSAL.CommitFreeAndNil(tr); except SUCURSAL.RollbackFreeAndNil(tr); end; finally SUCURSAL.Close; end; 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.
#6
Escrito 24 enero 2015 - 04:38
Hice lo siguiente:
el primer metodo inserta la cabecera del presupuesto, empleado,sucursal,cliente,y fechas, y el segundo el detalle, tengo entonces el cliente asi:
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.
delphi
procedure TServerMethods1.nuevopresupuesto(idc,ide,ids:integer;fechac, fechai,fechaf:string); var tr:TDBXTransaction; begin if (SUCURSAL.InTransaction) then raise Exception.Create('Hay una transacción pendiente'); SUCURSAL.Open; try try tr:=SUCURSAL.BeginTransaction(); with qipresu do begin Close; ParamByName('idc').AsInteger:=idc; ParamByName('ide').AsInteger:=ide; ParamByName('ids').AsInteger:=ids; ParamByName('fechac').AsString:=fechac; ParamByName('fechai').AsString:=fechai; ParamByName('fechaf').AsString:=fechaf; ExecSQL(); end; SUCURSAL.CommitFreeAndNil(tr); except SUCURSAL.RollbackFreeAndNil(tr); end; finally SUCURSAL.Close; end; end; procedure TServerMethods1.nuevodetallepresupuesto(idprodu:integer;cantidad,preciou:Double); var tr:TDBXTransaction; begin if (SUCURSAL.InTransaction) then raise Exception.Create('Hay una transacción pendiente'); SUCURSAL.Open; try try tr:=SUCURSAL.BeginTransaction(); begin with qipp do begin Close; ParamByName('idp').AsInteger:=qupresu.ExecSQL(); ParamByName('idprodu').AsInteger:=idprodu; ParamByName('preciou').AsFloat:=preciou; ParamByName('cantidad').AsFloat:=cantidad; ExecSQL(); end; SUCURSAL.CommitFreeAndNil(tr); end; except SUCURSAL.RollbackFreeAndNil(tr); end; finally SUCURSAL.Close; end; 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
a:=TServerMethods1Client.Create(ClientModule1.SQLConnection1.DBXConnection); idc:=1; ide:=1; ids:=1; fechac:=Eemititdo.Text; fechai:=Eemititdo.Text; fechaf:=Evalido.Text; a.nuevopresupuesto(idc,ide,ids,fechac,fechai,fechaf); l:=ClientModule1.cdspresu.RecordCount; x:=0; b:=TServerMethods1Client.Create(ClientModule1.SQLConnection1.DBXConnection); while x < l do begin inc(x); cantidad:=ClientModule1.cdspresucantidad.AsFloat; preciou:=ClientModule1.cdspresuprecio.AsFloat; idprodu:=ClientModule1.cdspresuidproducto.AsInteger; b.nuevodetallepresupuesto(idprodu,cantidad,preciou); end; 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.