Buscar:
Búsqueda avanzada
|
Navegar por categorías:
|
Solucionar error (Error de conectividad: No se puede obtener información específica del error. Probablemente el controlador no tiene recursos) |
||||
Aquest error es un bug de FoxPro i afecta a totes les versions desde la 7 a la 9, es produiex sempre que es dongui una excepció de la base de dades dins un stored procedure, pot ser un deadlock o una excepcio controlada per programa. L'error esta comprobat que falla conectant a altes base de dades (SQLSERVER) i fent servir altres controladors ODBC. L'error es produeix unicament si criden la SP amb select. ( SELECT * FROM NOM_STORED_PROCEDURE() ) o si es crida directament amb EXECUTE BLOCK.
Com reproduir el bug: Set Console On TEXT TO lcsql TEXTMERGE NOSHOW PRETEXT 7
execute block ( id integer =?m_codi) returns ( codi integer, nom varchar(40)) AS begin for select empresa,nom_emp from sys_empreses into :codi ,:nom do begin exception ERR_DADES_BD 'Error provocat desde un SP'; suspend; end end ENDTEXT aux=sqlprepare(nconh, lcsql,"SQLRESULT")
If aux<>-1 If sqlexec(nconh)=-1 ? "ERROR: "+Message() Else
Browse
Endif
Else ? Message() Endif = sqldisconnect(nconh)
Un cop es produiex aquest error, FoxPro deixa de funcionar correctament i totes les consultes a la base de dades donen aquest error,i la única opcio per continuar treballant es sortir del programa i tornar a entrar. Si comentem la linia 19 , així /* exception ERR_DADES_BD 'Error provocat desde un SP'; */ i tornem a executar el programa ens hauria de tornar un cursor amb les dades de les empreses de l'aplicació. Com solucionar-ho: Degut a que les crides a objectes ADO no es veuen afectades per aquest bug, el que s'ha fet es simular una crida SQL ODBC fent servir els objectes ADO, s'ha creat una nova funcio SQLEXEC_ADO, que sera que la haurem de cridar en comptes de la propia de fox. Afegir aquesta funció a LIBPROCS.PRG Function SQLEXEC_ADO
Parameters m_con,m_sql,m_cursor If Parameters()=2 m_cursor='' Endif sterr=1
LOCAL closeconection
IF VARTYPE(oconn)<>'O' && Si l'ojecte de la conexio no existeix el crea de nou closeconection=.t. Local oconn As adodb.Connection oconn = Createobject("ADODB.Connection") oconn.connectionstring = gpconstring oconn.Open() else
closeconection=.f. ENDIF Local ocommand As adodb.Command
ocommand = Createobject("ADODB.Command") ocommand.activeconnection = oconn Local ors As adodb.recordset
ors = Createobject("ADODB.RecordSet") ors.activeconnection = oconn Local oca As CursorAdapter
oca = Createobject("CursorAdapter") oca.Alias = "CURSORADAPTER1" && m_cursor oca.DataSourceType = "ADO" oca.Datasource = ors oca.SelectCmd = m_sql
If !oca.CursorFill(,,,ocommand)
= Aerror(aerrorarray) IF aerrorarray(1)<>1463 && El cursor no retorna dades sterr=-1 ELSE sterr=1 endif ELSE SELECT CURSORADAPTER1 try GO bottom CATCH ENDtry SELECT * FROM CURSORADAPTER1 INTO CURSOR (M_CURSOR) readwrite USE IN CURSORADAPTER1 oca.CursorDetach() sterr=1 Endif RELEASE OCA,ORS,OCOMMAND
IF closeconnection=.t.
RELEASE oconn ENDIF Return sterr
1. Afegir variable publica al programa ADSGEST.PRG i a INICI.PRG
PUBLIC gpconstring
2. Afegir la seguent linia despres de crear la cadena de conexión: aux = goReg.GetIniEntry(lcROLE,"BaseDades","ROLE",lcNomINI)
lcCadCon = "DSN=" + lcDSN + ";UID=" + lcUID + ";PWD=" + lcPWD + ";DB=" + lcDB + ";DBNAME=" + lcDB + ";ROLE=" + lcROLE
gpconstring = lcCadCon
3. Afegir la seguent linia despres de crear la cadena de conexión a INICI.PRG: ** lcaux = "DSN=IB_FOX;UID=pere;PWD=pere;DB=ROBY:f:\BD\adsgest.fdb;ROLE=TOTS;" gpconstring= lcaux
Nota: En cas de tenir dues bases de dades obertes a l'hora, será necesari tenir dues variables gpconstring diferentes.
4. Modificar les crides a stored procedures de l'aplicació. Unicament s'haurien de modificar les que cridem amb SELECT * FROM NOM_ STORED_PROCEDURE() EXEMPLE: aux = sqlexec(lnCon,"select * from V_LLISTAT(?gpEmpresa,?gpCanal,?lndatini,?lndatfin)","sqlresult") cambiar a : aux = sqlexec_ado(lnCon,"select * from V_LLISTAT(?gpEmpresa,?gpCanal,?lndatini,?lndatfin)","sqlresult")
Nota: La nova funcio sqlexec_ado, no utilitza el mateix identificador de conexió que fem servir (hcon, thisform.conexio) a l'aplicació, cada cop que es crida crea una nova conexio a la base de dades i un cop finalitzat el proces tanca la conexió. Per aquest motiu els comanments que es cridin d'aquesta menera no es veuran afectat per l'estat de les transaccions (auto o manual) en cas d'haverles canviat manualament en un proces anterior. Si es volem crear un proces amb multiples crides a Stored procedures englobades en una única transacció, haurem de iniciar la conexio ADO manualment i tambe finalitzar-la amb un COMMIT O ROLLBACK. Exemple: gpconstring="DRIVER=Firebird/InterBase(r) driver;UID=sysdba;PWD=masterkey;DBNAME=roby:f:\bd\ADSGEST.FDB" oconn = Createobject("ADODB.Connection") oconn.connectionstring = gpconstring oconn.Open() && Obre conexio oconn.BeginTrans && Inicia transaccio
lcerr=.f.
aux = sqlexec_ado(lnCon,"select * from V_PROCES1(?gpEmpresa,?gpCanal,?lndatini,?lndatfin)","sqlresult") if aux=-1 lcerr=.t. && Es produieix error endif aux = sqlexec_ado(lnCon,"select * from V_PROCES2(?gpEmpresa,?gpCanal,?lndatini,?lndatfin)","sqlresult")
if aux=-1 lcerr=.t. && Es produeix error endif aux = sqlexec_ado(lnCon,"select * from V_PROCES3(?gpEmpresa,?gpCanal,?lndatini,?lndatfin)","sqlresult")
if aux=-1 lcerr=.t. && Es produeix error endif if lcerr=.f.
oconn.Committrans && Tot correcte else oconn.Rollbacktrans && Desfa tots els procesos endif release oconn && Tanca conexió
|
Also read | |
![]() |
Evitar bloqueigs i deadlocks durant la execució de stored precedures |
Otras preguntas en esta categoría | |
» Más preguntas |