Page 1 of 2
MySql Nativa Transacciones. At. Mr. Rao
Posted: Wed Sep 15, 2021 1:10 pm
by Marcelo Roggeri
Hola muy buenos días desde Argentina, ante todo un saludo a todos.
Como bien dice el asunto estoy teniendo problemas al querer usar las transacciones usando la Nativa con MySql.
Les adjunto un trozo de codigo.
Code: Select all | Expand
TRY
oCn:BeginTransaction()
//--------------------------------------------------------------
//---Guardo los datos de la factura en el mayor de ventas
::tHoraComprobante:=TIME()
cCampos := "cpte_nombre,cpte_letra,cpte_ptovta,cpte_numero,cpte_fecha,cpte_hora,id_cliente,por_dcto,imp_dcto,netoNG,neto21,por_iva21,imp_iva21,neto105,por_iva105,imp_iva105,imp_ii,exento,imp_total,cotizacion,moneda,cae,caevto,caebar,nota,forma_pago,id_usuario,id_caja_maestro"
aDatas := {::nombreComprobante,::letraComprobante,::ptoVtaComprobante,::numeroComprobante,::dFechaComprobante,::tHoraComprobante,::id_cliente,::nPorDcto,::nImpDcto,::netoNG,::neto21,::nPorIva21,::impIva21,::neto105,::nPorIva105,::impIva105,::impII,::Exento,::nTotalCpte,::CotDolarAFIP,::cCodMon,VAL(::aRepFE[1,2]),::aRepFE[1,3],::aRepFE[1,7],::nota,::forma_pago,oApp:nIdUser,::nIdCaja}
oCn:Insert( "ventas_mayor", cCampos, aDatas )
...
// mas insert del mismo modo
...
CATCH oErr
oCn:RollBack()
msgInfo("Error al intentar guardar el Comprobante","Aviso")
lSave:= .F.
FINALLY
oCn:CommitTransaction()
END
Si en la tabla me falta definir un campo por ejemplo cpte_hora no graba el dato , no me da error y sigue el proceso de grabación del resto como me ocurrió.
Seguramente algo debo estar haciendo mal.
Esta forma de Insertar lo tome de un ejemplo en este Foro que nos compartió el Mr Rao
Asi que quedo a la espera de los que saben.
Un abrazo a la distancia.
Marcelo
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Thu Sep 16, 2021 2:25 am
by nageswaragunupudi
1) What is the data type of cpte_hora? Is it CHAR(8) or VARCHAR(8)?
2) TRY/CATCH does not work. Because if there is a MySql error while inserting, no runtime error is raised. Instead, oCn:nError is set to mysql error number and oCn:cError is set to mysql error description.
So, after oCn:Insert(...), please check
and let us know the result.
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Thu Sep 16, 2021 9:52 am
by Ariel
Mr. Rao,
si las try/catch no funciona para detectar un error, como se hace una insercion multiple de tablas el rollback ?
Ejemplo:
oCon:insert( "tabla1".... )
oCon:insert( "tabla2".... )
oCon:insert( "tabla3".... )
oCon:insert( "tabla4".... )
if oCon:nError <> 0
? "Error "
endif
oCon:insert( "tabla5".... )
o sea, como hacemos el RollBack() de las tablas 1,2 y 3 ???
Saludos
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Thu Sep 16, 2021 7:42 pm
by Ariel
????
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Thu Sep 16, 2021 9:19 pm
by Marcelo Roggeri
Mr Rao,
La hora es un tipo de dato VARCHAR(8)
Saludos
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Thu Sep 16, 2021 9:27 pm
by Marcelo Roggeri
Mr Rao
Adjunto la imagen del mensaje de error

Saludos
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Thu Sep 16, 2021 10:41 pm
by carlos vargas
Me uno a la pregunta de ariel, es lo unico que me impide migrar a mysql de fwh,
por mas que le doy vuelta no lo encuentro solucion a no ser que por cada instruccion sql que se realice se este verificando si hay error, lo cual considero que rompe con la idea de las transacciones... y incrementa el codigo...
o talvez hay algo mas facil que rao ha impementado, sabiendo como se ha currado esa parte no me extrañaria..
salu2
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Thu Sep 16, 2021 10:52 pm
by MarioG
Hola!
Solo ratificar expuesto
Hago lo siguiente
A los efectos de guardar varios documentos cheques, lo hago de la siguiente manera:
Code: Select all | Expand
cFieldsBC := "id_banco,id_cuenta,FeAcredita,id_FCompra,Detalle,Monto,idTransTipo,id_user", ; // campos de la tabla Banking
luego genero un multiarray con varias líneas (cada una relacionada con los campos arriba mencionado)
Code: Select all | Expand
lGuardo:= !( ::oConn:Insert( "banking", cFieldsBC, aChequesBC ) == 0 )
Con esta forma de expresar pasan dos cosas:
1. Mi interpretacion fue que si :Insert() devuelve el nro de registros insertados; y por el contrario, ante alguna razon debería devolver 0 (cero).
Lo que no sucede... pues devuelve NIL!
2.- Si por error mio escribo cFieldsBC, sin uno de los campos de manera que escribo solo 7 campos, y el array tiene datos en los 8 campos.... GUARDA IGUAL!
Quizas esto tenga algún significado con el error que provoco
cFieldsBC := "id_banco,id_cuenta,FeAcredita,id_FCompra,Detalle,Monto,idTransTipo,id_user"
lo escribo cFieldsBC := "id_banco,id_cuenta,,id_FCompra,Detalle,Monto,idTransTipo,id_user" // Falta FeAcredita
Al campo FeAcredita en la tabla lo tengo definido con DEFAULT '0000-00-00'. O sea que :Insert() lo guarda con ese dato
No obstante si el nro de campos en la variable es menor que el numero de campos en el array... no debería dar error?
quedo atento
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Fri Sep 17, 2021 3:52 am
by nageswaragunupudi
Marcelo Roggeri wrote:Mr Rao
Adjunto la imagen del mensaje de error

Saludos
Does it mean there is no field by name "cpte_hora" in the table?
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Fri Sep 17, 2021 10:08 am
by Ariel
Mr. Rao,
ese es un ejemplo provocado por error en la programación, el tema es que el comando :insert() devuelve Nil y sigue con la ejecución de sentencias, un verdadero desastre, el método debería (a mi entender y coincido con Carlos) generar el error que provoque la salida por el CATCH.
Saludos.
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Fri Sep 17, 2021 11:15 am
by nageswaragunupudi
Please try:
Code: Select all | Expand
local lSaved := .f.
oCn:BeginTransaction()
TRY
if Empty( oCn:Insert( ... ) ); THROW(); endif
if Empty( oCn:Insert( ... ) ); THROW(); endif
if Empty( oCn:Insert( ... ) ); THROW(); endif
lSaved := .t.
CATCH
lSaved := .f.
oCn:RollBack()
END
if lSaved
oCn:CommitTransaction()
endif
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Fri Sep 17, 2021 5:03 pm
by carlos vargas
Hace años que uso tmysql con estos cambios, y me ha funcionado bien, me gusta mucho la implementación de mysql en fwh pero veo que tengo que hacer muchos cambios 
Code: Select all | Expand
CLASS TMySQLServer
....
EXPORTED:
DATA pMySQL
DATA cDBName, cSchema
DATA lTraceLog
DATA lThrowError INIT FALSE //para controlar cuando quiero que me reviente el error
....
METHOD Execute( cSqlCmd, aParams ) CLASS TMySQLServer
LOCAL nRet, oErr
IF hb_IsArray( aParams )
cSqlCmd := EvalQueryParams( cSqlCmd, aParams, ::pMySql )
ENDIF
IF ::lTraceLog
TraceLog( cSqlCmd )
ENDIF
IF hb_isBlock( ::bOnLoadQuery )
Eval( ::bOnLoadQuery, Self )
ENDIF
::lError := FALSE
::cError := ""
::nError := 0
nRet := mysql_real_query( ::pMySQL, cSqlCmd )
IF hb_isBlock( ::bOnAfterQuery )
Eval( ::bOnAfterQuery, Self )
ENDIF
IF !( nRet == MYSQL_QUERY_SUCCESS )
::lError := TRUE
::cError := ::ErrorTxt()
::nError := ::ErrNo()
IF ::lThrowError //aca es como lo implemento
oErr := ErrorNew()
oErr:Args := { ::pMySQL, cSqlCmd, aParams }
oErr:CanDefault := FALSE
oErr:CanRetry := FALSE
oErr:CanSubstitute := FALSE
oErr:GenCode := EG_SYNTAX
oErr:Severity := ES_ERROR
oErr:SubSystem := "TMYSQL-(EXECUTE)"
oErr:Operation := cSqlCmd
oErr:SubCode := ::nError
oErr:Description := ::cError
Eval( ErrorBlock(), oErr )
ENDIF
ENDIF
RETURN !::lError
....
aca es como lo uso...STATIC PROCEDURE NuevoPrestamo_Grabar()
LOCAL i, cSqlDetalle := "INSERT INTO prestamosdet (num_pres,cuota_no,fecha_prog,valor_prog,estado) VALUES "
LOCAL lGrabado := FALSE
LOCAL cInfo
FOR i := 1 TO Len( aTabla )
cSqlDetalle += "( &1, " + Var2Str( aTabla[ i, TABLA_ABO_NO ] ) + "," + ;
Var2Str( aTabla[ i, TABLA_ABO_FECHA ] ) + "," + ;
Var2Str( aTabla[ i, TABLA_ABO_VALPROG ] ) + "," + "'A'),"
NEXT
cSqlDetalle := hb_StrShrink( cSqlDetalle )
oServer:lThrowError := TRUE //aca lo activo
TRY
oServer:BeginTransaction()
IF ( nPresNum := IncCount( "control", "cont_pres" ) ) > 0
oServer:Insert2( "prestamosmas", { { "num_ruta" , nRutaCob }, ;
{ "num_clie" , nClieNum }, ; /*datos de cliente*/
{ "nombre" , cClieNom }, ;
{ "cedula" , cClieCed }, ;
{ "ciudad" , cClieCiu }, ;
{ "direccion" , cClieDir }, ;
{ "telefonos" , cClieTel }, ;
{ "num_pres" , nPresNum }, ; /*datos del prestamo*/
{ "importe" , nImporte }, ;
{ "interes" , nInteres }, ;
{ "cuotas" , nCuotas }, ;
{ "modalidad_pago", nModalidad }, ;
{ "valor_cuota" , nValorCuota }, ;
{ "total" , nTotal }, ;
{ "fecha_ent" , dFechaEnt }, ;
{ "fecha_ini" , dFechaIni }, ;
{ "fecha_fin" , dFechaFin }, ;
{ "abonado" , 0 }, ;
{ "estado" , "A" }, ;
{ "nota" , cNota } } )
oServer:Execute( cSqlDetalle, { nPresNum } )
IF lRestructuracion
cInfo := "Prestamo restructurado: " + hb_NToS( nOldNumPres )
oServer:Execute( "UPDATE prestamosmas SET estado = &1, nota = concat( nota, &2 ) WHERE num_pres=&3", { "R", cInfo, nOldNumPres } )
ENDIF
ENDIF
oServer:Commit()
lGrabado := TRUE
CATCH oError
ShowError( oError )
oServer:Rollback()
END
oServer:lThrowError := FALSE //aca lo desactivo
IF lGrabado
NuevoPrestamo_MostrarNumero()
IF MsgNoYes( "Desea imprimir contrato del prestamo?" )
NuevoPrestamo_Imprimir()
ENDIF
IF lRestructuracion
oDlgE:End()
ELSE
NuevoPrestamo_Limpiar1( TRUE )
oDlgE:Update()
oBtnSearch:SetFocus()
ENDIF
ENDIF
RETURN lGrabado
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Fri Sep 17, 2021 5:03 pm
by carlos vargas
Hace años que uso tmysql con estos cambios, y me ha funcionado bien, me gusta mucho la implementación de mysql en fwh pero veo que tengo que hacer muchos cambios 
Code: Select all | Expand
CLASS TMySQLServer
....
EXPORTED:
DATA pMySQL
DATA cDBName, cSchema
DATA lTraceLog
DATA lThrowError INIT FALSE //para controlar cuando quiero que me reviente el error
....
METHOD Execute( cSqlCmd, aParams ) CLASS TMySQLServer
LOCAL nRet, oErr
IF hb_IsArray( aParams )
cSqlCmd := EvalQueryParams( cSqlCmd, aParams, ::pMySql )
ENDIF
IF ::lTraceLog
TraceLog( cSqlCmd )
ENDIF
IF hb_isBlock( ::bOnLoadQuery )
Eval( ::bOnLoadQuery, Self )
ENDIF
::lError := FALSE
::cError := ""
::nError := 0
nRet := mysql_real_query( ::pMySQL, cSqlCmd )
IF hb_isBlock( ::bOnAfterQuery )
Eval( ::bOnAfterQuery, Self )
ENDIF
IF !( nRet == MYSQL_QUERY_SUCCESS )
::lError := TRUE
::cError := ::ErrorTxt()
::nError := ::ErrNo()
IF ::lThrowError //aca es como lo implemento
oErr := ErrorNew()
oErr:Args := { ::pMySQL, cSqlCmd, aParams }
oErr:CanDefault := FALSE
oErr:CanRetry := FALSE
oErr:CanSubstitute := FALSE
oErr:GenCode := EG_SYNTAX
oErr:Severity := ES_ERROR
oErr:SubSystem := "TMYSQL-(EXECUTE)"
oErr:Operation := cSqlCmd
oErr:SubCode := ::nError
oErr:Description := ::cError
Eval( ErrorBlock(), oErr )
ENDIF
ENDIF
RETURN !::lError
....
aca es como lo uso...STATIC PROCEDURE NuevoPrestamo_Grabar()
LOCAL i, cSqlDetalle := "INSERT INTO prestamosdet (num_pres,cuota_no,fecha_prog,valor_prog,estado) VALUES "
LOCAL lGrabado := FALSE
LOCAL cInfo
FOR i := 1 TO Len( aTabla )
cSqlDetalle += "( &1, " + Var2Str( aTabla[ i, TABLA_ABO_NO ] ) + "," + ;
Var2Str( aTabla[ i, TABLA_ABO_FECHA ] ) + "," + ;
Var2Str( aTabla[ i, TABLA_ABO_VALPROG ] ) + "," + "'A'),"
NEXT
cSqlDetalle := hb_StrShrink( cSqlDetalle )
oServer:lThrowError := TRUE //aca lo activo
TRY
oServer:BeginTransaction()
IF ( nPresNum := IncCount( "control", "cont_pres" ) ) > 0
oServer:Insert2( "prestamosmas", { { "num_ruta" , nRutaCob }, ;
{ "num_clie" , nClieNum }, ; /*datos de cliente*/
{ "nombre" , cClieNom }, ;
{ "cedula" , cClieCed }, ;
{ "ciudad" , cClieCiu }, ;
{ "direccion" , cClieDir }, ;
{ "telefonos" , cClieTel }, ;
{ "num_pres" , nPresNum }, ; /*datos del prestamo*/
{ "importe" , nImporte }, ;
{ "interes" , nInteres }, ;
{ "cuotas" , nCuotas }, ;
{ "modalidad_pago", nModalidad }, ;
{ "valor_cuota" , nValorCuota }, ;
{ "total" , nTotal }, ;
{ "fecha_ent" , dFechaEnt }, ;
{ "fecha_ini" , dFechaIni }, ;
{ "fecha_fin" , dFechaFin }, ;
{ "abonado" , 0 }, ;
{ "estado" , "A" }, ;
{ "nota" , cNota } } )
oServer:Execute( cSqlDetalle, { nPresNum } )
IF lRestructuracion
cInfo := "Prestamo restructurado: " + hb_NToS( nOldNumPres )
oServer:Execute( "UPDATE prestamosmas SET estado = &1, nota = concat( nota, &2 ) WHERE num_pres=&3", { "R", cInfo, nOldNumPres } )
ENDIF
ENDIF
oServer:Commit()
lGrabado := TRUE
CATCH oError
ShowError( oError )
oServer:Rollback()
END
oServer:lThrowError := FALSE //aca lo desactivo
IF lGrabado
NuevoPrestamo_MostrarNumero()
IF MsgNoYes( "Desea imprimir contrato del prestamo?" )
NuevoPrestamo_Imprimir()
ENDIF
IF lRestructuracion
oDlgE:End()
ELSE
NuevoPrestamo_Limpiar1( TRUE )
oDlgE:Update()
oBtnSearch:SetFocus()
ENDIF
ENDIF
RETURN lGrabado
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Fri Sep 17, 2021 5:06 pm
by Marcelo Roggeri
Mr. Rao
Si ese campo falta lo borre intencionalmente para ocasionar el error.
Esto ultimo que usted puso anda
Code: Select all | Expand
IF EMPTY( oCn:Insert( "ventas_mayor", cCampos, aDatas ) ); THROW(); endif
y por consiguiente hace el RollBack.
Otra consulta, ayer habia probado de esta manera de acuerdo a un sample
Code: Select all | Expand
oCn:Insert( "ventas_mayor", cCampos, aDatas )
if oCn:nError != 0
BREAK
endif
y también hace el RollBack
Muchas gracias por la ayuda.
Saludos desde Argentina
Marcelo
Re: MySql Nativa Transacciones. At. Mr. Rao
Posted: Fri Sep 17, 2021 6:26 pm
by nageswaragunupudi
Mr. Marcelo
BREAK works for you, because you are using Harbour. You may continue using BREAK as you proposed.
It does not work with xHarbour.