Base de coneixement
ADS Anàlisi/Disseny de Soft, S.L.U.
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)

Visitas: 645
Posted: 06. October 2014
by:
Updated: 18. June 2015
by:

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
gpconstring="DRIVER=Firebird/InterBase(r) driver;UID=sysdba;PWD=masterkey;DBNAME=roby:f:\bd\ADSGEST.FDB"
nconh= Sqlstringconnect(gpconstring)
Clear
? "Connectat"
m_codi=1

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;"
lcaux = "DSN=IB_FOX;UID=pere;PWD=pere;DB=ROBY:f:\BD\adsgest.fdb;ROLE=TOTS;DBNAME=ROBY:f:\BD\adsgest.fdb;"

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
document Evitar bloqueigs i deadlocks durant la execució de stored precedures

Otras preguntas en esta categoría
» Más preguntas



RSS