FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour PARA RAFAEL CARMONA (THEFULL)
Posts: 537
Joined: Mon Jan 16, 2006 03:42 PM
PARA RAFAEL CARMONA (THEFULL)
Posted: Thu Jun 25, 2009 04:13 PM

Rafa:

Para trabajar con Transaccion con 2 o mas tablas con (ADO), como seria, a la vez si hay error quiero saber en q parte ocurrio y linea

Saludos

Posts: 537
Joined: Mon Jan 16, 2006 03:42 PM
Re: PARA RAFAEL CARMONA (THEFULL)
Posted: Sat Jun 27, 2009 06:05 PM

Que pena que nadien tampoco trabaje con Transacciones con mas de una tablas

Saludos

Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: PARA RAFAEL CARMONA (THEFULL)
Posted: Sun Jun 28, 2009 05:12 PM

En ADO, tienes un gestion de errores, que te indica que error se a producido.
A ver si ma帽ana puedo subirte dicha clase, que es el error que devuelve ADO.

Lo que yo realizo para ello es un control dentro de un try/catch, donde me guardo la query a
ejecutar en un variable, por si falla, e indico el error de ADO m谩s la sentencia que ha generado ese error.

Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: PARA RAFAEL CARMONA (THEFULL)
Posted: Mon Jun 29, 2009 08:25 AM
Supongamos que tienes el objeto conexion; ( Las clases que use te las publico abajo en el mismo post )

Code (fw): Select all Collapse
 聽 try
聽 聽 聽 cSql := "bla bbla bla"

聽 聽 catch oError
聽 聽 聽 聽 ::oConnection:RollBackTrans()
聽 聽 聽 聽 MsgInfo ("ERROR. Se ha realizado ROLLBACK." )
聽 聽 聽 聽 if Empty( ::oConnection:oError:aErrors ) // No son errores de ADO, errores Harbour
聽 聽 聽 聽 聽 聽MsgStop( oError:Operation + CRLF + oError:Description, "" )
聽 聽 聽 聽 else
聽 聽 聽 聽 聽 聽MsgStop( "Falla: "+ CRLF + 聽cSql )
聽 聽 聽 聽 endif
聽 聽 聽 聽 ::oConnection:oError:ShowErrors() 聽 聽// Muestra el error que nos d谩 el SQL

聽 聽 end


Esto es todo, con esto he resuelto casi el 100% de los errores , tanto por parte de Harbour como por parte de ADO.

Te publico aqu铆 el c贸digo fuente de las clases de ADO.
Code (fw): Select all Collapse
/*
聽* Proyecto: adolib
聽* Fichero: adoConn.prg
聽* Descripci贸n: Objeto Conexi贸n de ADO
聽* Autor: Jos茅 Luis Capel - <!-- m --><a class="postlink" href="http://www.capelblog.com">http://www.capelblog.com</a><!-- m -->
聽* Fecha: 13/11/2005
聽* CopyRight: Jos茅 Luis Capel - 2005 Todos los derechos reservados al autor
聽* Adaptaciones menores por Rafa Carmona
聽*/

#define CRLF chr(13)+chr(10)
#xcommand DEFAULT <x1> TO <v1> [, <xn> TO <vn> ] => ;
聽 聽 聽 聽 聽 IF <x1> == Nil ; <x1> := <v1> ; ENDIF 聽 聽 ;
聽 聽 聽 聽 聽 [; IF <xn> == Nil ; <xn> := <vn> ; ENDIF ]

#include "hbclass.ch"
#include "ado.ch"


CLASS tAdoConn

聽 聽 聽 DATA aObjects 聽 聽 AS ARRAY 聽INIT {} 聽//Diferentes Objectos creados con tAdoConn
聽 聽 聽 DATA oConnection 聽AS OBJECT
聽 聽 聽 DATA oError

聽 聽 聽 // ----------------------------------> Para la conexi贸n
聽 聽 聽 DATA cConnectionString 聽AS CHARACTER
聽 聽 聽 DATA cUserId 聽 聽 聽 聽 聽 聽AS CHARACTER
聽 聽 聽 DATA cPassword 聽 聽 聽 聽 聽AS CHARACTER
聽 聽 聽 // ----------------------------------> Para la conexi贸n

聽 聽 聽 METHOD New()

聽 聽 聽 METHOD Open( cConnString, cUserId, cPassword, nOptions )
聽 聽 聽 METHOD Close()
聽 聽 聽 METHOD Execute( cCommand, nRecords, nOptions )
聽 聽 聽 METHOD RollBackTrans()
聽 聽 聽 METHOD CommitTrans()
聽 聽 聽 METHOD BeginTrans()

ENDCLASS


METHOD New() CLASS tAdoConn

聽 聽 聽 聽LOCAL oError
聽 聽 聽 聽LOCAL lResult

聽 聽 聽 聽::oError := TAdoError():New()

聽 聽 聽 聽lResult := .T.

聽 聽 聽 聽TRY
聽 聽 聽 聽 聽 ::oConnection := CreateObject("ADODB.Connection")
聽 聽 聽 聽CATCH oError
聽 聽 聽 聽 聽 lResult := .F.
聽 聽 聽 聽 聽 MsgStop( oError:Operation, "Ado Connection" )
聽 聽 聽 聽END

聽 聽 聽 聽// ------------------------> Valores por defecto!!
聽 聽 聽 聽IF lResult
聽 聽 聽 聽 聽 ::oConnection:CommandTimeOut 聽 聽 聽 := 5
聽 聽 聽 聽 聽 ::oConnection:ConnectionTimeOut 聽 聽:= 10
聽 聽 聽 聽 聽 ::oConnection:CursorLocation 聽 聽 聽 := adUseClient
聽 聽 聽 聽ENDIF
聽 聽 聽 聽// ------------------------> Valores por defecto!!


RETURN Self


METHOD Open ( cConnString, cUserId, cPassword, nOptions ) CLASS tAdoConn

聽 聽 聽 聽LOCAL oError
聽 聽 聽 聽LOCAL lResult

聽 聽 聽 聽DEFAULT cUserId 聽 TO NIL
聽 聽 聽 聽DEFAULT cPassword TO NIL
聽 聽 聽 聽DEFAULT nOptions 聽TO NIL

聽 聽 聽 聽lResult := .T.

聽 聽 聽 聽TRY
聽 聽 聽 聽 聽::oConnection:Open( cConnString, cUserId, cPassword, nOptions)
聽 聽 聽 聽CATCH oError
聽 聽 聽 聽 聽 lResult := .F.
聽 聽 聽 聽 聽 MsgStop( oError:Operation+CRLF+oError:Description,"Ado Connection")
聽 聽 聽 聽 聽 ::oError:Connection( ::oConnection )
聽 聽 聽 聽 聽 ::oError:ShowErrors()
聽 聽 聽 聽END

RETURN lResult

METHOD BeginTrans() CLASS tAdoConn
聽 聽LOCAL oError
聽 聽LOCAL lResult

聽 聽lResult := .T.

聽 聽TRY
聽 聽 聽::oConnection:BeginTrans()
聽 聽CATCH oError
聽 聽 聽 lResult := .F.
聽 聽 聽 MsgStop(oError:Operation+CRLF+oError:Description,"Ado Connection")
聽 聽 聽 ::oError:Connection( ::oConnection )
聽 聽 聽 ::oError:ShowErrors()
聽 聽END

RETURN lResult

METHOD CommitTrans() CLASS tAdoConn
聽 聽LOCAL oError
聽 聽LOCAL lResult

聽 聽lResult := .T.

聽 聽TRY
聽 聽 聽::oConnection:CommitTrans()
聽 聽CATCH oError
聽 聽 聽 lResult := .F.
聽 聽 聽 MsgStop(oError:Operation+CRLF+oError:Description,"Ado Connection")
聽 聽 聽 ::oError:Connection( ::oConnection )
聽 聽 聽 ::oError:ShowErrors()
聽 聽END

RETURN lResult

METHOD RollBackTrans() CLASS tAdoConn
聽 聽LOCAL oError
聽 聽LOCAL lResult

聽 聽lResult := .T.

聽 聽TRY
聽 聽 聽::oConnection:RollBackTrans()
聽 聽CATCH oError
聽 聽 聽 lResult := .F.
聽 聽 聽 MsgStop(oError:Operation+CRLF+oError:Description,"Ado Connection")
聽 聽 聽 ::oError:Connection( ::oConnection )
聽 聽 聽 ::oError:ShowErrors()
聽 聽END

RETURN lResult



METHOD Close() CLASS tAdoConn

聽 聽 聽 聽LOCAL oError
聽 聽 聽 聽LOCAL lResult

聽 聽 聽 聽lResult := .T.

聽 聽 聽 聽TRY
聽 聽 聽 聽 聽 ::oConnection:Close()
聽 聽 聽 聽CATCH oError
聽 聽 聽 聽 聽 lResult := .F.
聽 聽 聽 聽 聽 MsgStop(oError:Operation+CRLF+oError:Description,"Ado Connection")
聽 聽 聽 聽 聽 ::oError:Connection( ::oConnection )
聽 聽 聽 聽 聽 ::oError:ShowErrors()
聽 聽 聽 聽END

RETURN lResult


METHOD Execute( cCommand, nRecords, nOptions ) CLASS tAdoConn
聽 聽 聽 聽LOCAL oError, cError, oErr
聽 聽 聽 聽LOCAL lResult

聽 聽 聽 聽DEFAULT nRecords 聽TO 0
聽 聽 聽 聽DEFAULT nOptions 聽TO NIL

聽 聽 聽 聽lResult := .T.

聽 聽 聽 聽TRY
聽 聽 聽 聽 聽::oConnection:Execute( cCommand, @nRecords, nOptions)
聽 聽 聽 聽CATCH oErr
聽 聽 聽 聽 聽 ::oError:Connection( ::oConnection )
聽 聽 聽 聽 聽 lResult := .F.
聽 聽 聽 聽 聽 Throw( oErr )
聽 聽 聽 聽END

RETURN lResult


CLASS TAdoError
聽 聽 聽 DATA aErrors
聽 聽 聽 DATA oErrorDB
聽 聽 聽 METHOD New()
聽 聽 聽 METHOD Clean() INLINE ::aErrors := {}
聽 聽 聽 METHOD Connection( oConnection )
聽 聽 聽 METHOD ShowErrors()
END CLASS

METHOD New( lCreateError ) CLASS TAdoError

聽 聽::aErrors := {}
聽 聽/* TODO: Pendiente de I+D
聽 聽if lCreateError
聽 聽 聽 ::oErrorDB := CreateObject( "ADODB.Error")
聽 聽endif
聽 聽*/
RETURN Self

METHOD Connection( oConnection ) CLASS TAdoError

聽 聽 Local oError, cError := ""

聽 聽 ::Clean()

聽 聽 For Each oError In oConnection:Errors
聽 聽 聽 聽 cError := "Error #" + cValtoChar( oError:Number ) + CRLF +;
聽 聽 聽 聽 聽 聽 聽 聽 聽 " 聽 " 聽+ oError:Description + CRLF +;
聽 聽 聽 聽 聽 聽 聽 聽 聽 " 聽 (Source: " + oError:Source + ")" + CRLF +;
聽 聽 聽 聽 聽 聽 聽 聽 聽 " 聽 (SQL State: " + oError:SQLState + ")" + CRLF +;
聽 聽 聽 聽 聽 聽 聽 聽 聽 " 聽 (NativeError: " + cValToChar( oError:NativeError ) + ")"
聽 聽 聽 聽 AADD( ::aErrors, cError )
聽 聽 Next

RETURN NIL

METHOD ShowErrors( ) CLASS TAdoError
聽 聽 Local cError := ""

聽 聽 For Each cError In ::aErrors
聽 聽 聽 聽 MsgStop( cError )
聽 聽 next

RETURN NIL


//---------------------------------------------------------------------
//---------------------------------------------------------------------
CLASS tAdoCommand
聽 聽 DATA oCmd 聽 聽 聽 聽 聽//Objeto ADO Command
聽 聽 DATA oParameters
聽 聽 DATA oError
聽 聽 DATA oConnection

聽 聽 METHOD New( oConnection ) CONSTRUCTOR
聽 聽 METHOD Type( nType ) INLINE ::oCmd:CommandType := nType
聽 聽 METHOD Text( cText ) INLINE ::oCmd:CommandText := cText
聽 聽 METHOD GetADOCommand() 聽INLINE ::oCmd
END CLASS

METHOD New( oConnection ) CLASS tAdoCommand

聽 聽 聽 聽LOCAL oHErr

聽 聽 聽 聽::oError := TAdoError():New()
聽 聽 聽 聽::oConnection := oConnection
聽 聽 聽 聽TRY
聽 聽 聽 聽 聽 ::oCmd := CreateObject("ADODB.Command")
聽 聽 聽 聽CATCH oHErr
聽 聽 聽 聽 聽 MsgStop( "ERROR EN tAdoCommand")
聽 聽 聽 聽 聽 ::oError:Connection( ::oConnection:oConnection )
聽 聽 聽 聽 聽 Throw( oHErr )
聽 聽 聽 聽END

聽 聽 聽 聽::oCmd:ActiveConnection := ::oConnection:oConnection

RETURN Self

//---------------------------------------------------------------------
//---------------------------------------------------------------------
CLASS TAdoStoreProc FROM TAdoCommand
聽 聽 聽 METHOD New( cText, oConnection ) CONSTRUCTOR
聽 聽 聽 METHOD Execute()
END CLASS

METHOD New( cText, oConnection ) CLASS tAdoStoreProc
聽 Local oHErr

聽 try
聽 聽 Super:New( oConnection )
聽 聽 ::Type( adCmdStoredProc )
聽 聽 ::Text( cText )
聽 聽 ::oCmd:Parameters:Refresh()
聽 catch oHErr
聽 聽 MsgStop( "ERROR EN tAdoStoreProc")
聽 聽 ::oError:Connection( ::oConnection:oConnection )
聽 聽 Throw( oHErr )
聽 聽end

RETURN Self

METHOD Execute( ) CLASS tAdoStoreProc
聽 聽 聽 聽LOCAL oError, cError, oErr
聽 聽 聽 聽LOCAL lResult

聽 聽 聽 聽lResult := .T.

聽 聽 聽 聽TRY
聽 聽 聽 聽 聽::oCmd:Execute()
聽 聽 聽 聽CATCH oErr
聽 聽 聽 聽 聽 MsgStop( "ERROR EN tAdoCommand EXECUTE")
聽 聽 聽 聽 聽 ::oError:Connection( ::oConnection:oConnection )
聽 聽 聽 聽 聽 lResult := .F.
聽 聽 聽 聽 聽 Throw( oErr )
聽 聽 聽 聽END

RETURN lResult
Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 537
Joined: Mon Jan 16, 2006 03:42 PM
Re: PARA RAFAEL CARMONA (THEFULL)
Posted: Mon Jun 29, 2009 08:44 PM
Rafa gracias por responder mira yo lo hago asi:

oCnx:oConnection:BeginTrans()
lRet:= .T.

TRY
oCnx:oConnection:Execute( cSql1 ) //Tabla 1 de Cliente
oCnx:oConnection:Execute( cSql2 ) //Tabla 2 de Cuenta corriente
oCnx:oConnection:Execute( cSql3 ) //Tabla 3 de Caja

CATCH oErr
oCnx:oConnection:RollBackTrans()
lRet:= .f.
MsgInfo( "Descripci贸n : " + oErr:Description + CRLF + ;
"Error Nativo : " + Str(oErr:NativeError) + CRLF + ;
"N煤mero Error : " + Str(oErr:Number) + CRLF + ;
"Origen : " + oErr:Source + CRLF + ;
"Estado SQL : " + oErr:SQLState )


FINALLY
If ( lRet )
oCnx:oConnection:Committrans()
MsgStop( 'El movimiento fue grabado.' )
Else
MsgStop( 'El movimiento NO fue grabado.Intente Nuevamente' )
Endif
END

cuando lo hago con mas de dos tablas me sale error en estas lineas:
"Error Nativo : " + Str(oErr:NativeError) + CRLF + ;
"N煤mero Error : " + Str(oErr:Number) + CRLF + ;
"Origen : " + oErr:Source + CRLF + ;
"Estado SQL : " + oErr:SQLState


no asi en la Descripci贸n : " + oErr:Description ,,,,,, en esta me sale bien son esa linea y el error es el siguiente:

Application
===========
Path and name: C:\SYSTEMA\SYSBARO\MENUX.Exe (32 bits)
Size: 956,928 bytes
Time from start: 0 hours 0 mins 16 secs
Error occurred at: 29/06/2009, 16:43:50
Error description: Error BASE/1004 Class: 'ERROR' has no exported method: NATIVEERROR
Args:
[ 1] = O Object

eso me pasa


Saludos
Posts: 1283
Joined: Fri Feb 10, 2006 02:34 PM
Re: PARA RAFAEL CARMONA (THEFULL)
Posted: Tue Jun 30, 2009 06:24 AM
Bones,

Prueba asi:

Code (fw): Select all Collapse
 聽TRY

聽 聽 聽::oRS := ::oConn:Execute( cCommand, @nRecAff, nOptions)

聽 聽CATCH oError

聽 聽 聽lResult := .F.

聽 聽 聽FOR EACH oError IN ::oConn:Errors
聽 聽 聽 聽 聽::cError := TAdoError( oError, ::lMessage )
聽 聽 聽NEXT

聽 END


Code (fw): Select all Collapse
*-------------------------------------
FUNCTION TAdoError( oError, lMessage )
*-------------------------------------
聽 聽 LOCAL cError := .T.

聽 聽 DEFAULT lMessage := .T.

* 聽 聽 聽 聽MsgStop( 'Error: ' + oError:description + ' => ' + CRLF + ;
* 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 oError:operation, 'Sistema' 聽)

聽 聽 cError := "Descripci戮n 聽" 聽+ Chr( VK_TAB) + ": "  + oError:Description + CRLF + CRLF + 聽;
聽 聽 聽 聽 聽 聽 聽 "Error Nativo 聽" + Chr( VK_TAB) + ": " 聽+ Ltrim(Str(oError:NativeError)) + CRLF + ;
聽 聽 聽 聽 聽 聽 聽 "N路mero Error 聽" + Chr( VK_TAB) + ": " 聽+ Ltrim(Str(oError:Number)) 聽 聽 聽+ CRLF + ;
聽 聽 聽 聽 聽 聽 聽 "Origen 聽 聽 聽 聽" + Chr( VK_TAB) + ": " 聽+ oError:Source + CRLF + ;
聽 聽 聽 聽 聽 聽 聽 "Estado SQL 聽" 聽 + Chr( VK_TAB) + ": " 聽+ oError:SQLState

聽 聽 IF lMessage
聽 聽 聽 聽MsgStop( cError, 'Ado Connection' )
聽 聽 ENDIF

RETU cError
Salutacions, saludos, regards

"...programar es f谩cil, hacer programas es dif铆cil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
HIX -> https://github.com/carles9000/hix

Continue the discussion