Driver ODBC e VO

Forum dedicato ai programmatori di X# in lingua italiana – Italian language forum

Moderator: wriedmann

Post Reply
User avatar
claudiocarletta
Posts: 101
Joined: Sat Sep 05, 2020 8:56 am

Driver ODBC e VO

Post by claudiocarletta »

Salve a tutti

Nel programma per il quale vi chiedo aiuto, utilizzo VO, come database MySQL connesso tramite "ODBC 8.0 ANSI Driver a 32 bit".
Ho una transazione MySQL che mi sta dando saltuariamente dei problemi. Se eseguo la stessa transazione tramite Workbench viene eseguita senza nessun problema.
All'interno del programma ho decine di transazioni simili e nessuna mi sta dando problemi.
Questa è la Stored Procedure che richiamo:
------------------------------------------
CREATE DEFINER=`root`@`localhost` PROCEDURE `RientroLibro3`(in IdRec INT, in DataReso char(12), in P_ISBN char(13))
BEGIN
START TRANSACTION;
UPDATE `biblioteca`.`libri_alunno`
SET `reso` = DataReso
WHERE (`idlibri_alunno` = IdRec);

INSERT INTO biblioteca.giacenza (ISBN, giacenza) VALUES (P_ISBN, 1)
ON DUPLICATE KEY UPDATE giacenza = giacenza + 1;
COMMIT;
END
--------------------------------------

Queste sono le righe di programma incriminate in cui richiamo la procedura:
-------------------------------------

METHOD ConfermaUno(Multiplo as LOGIC)
local DataConsegna as string
local NumeroRecord as string
local cISBN as string
local sLibClass as string
local sClassCer as string
local nProve as int

// Preparazione parametri Stored Procedure
NumeroRecord := LTrim(Transform(SELF:oLibri:FIELDGET(#IDREC), "9999999999"))
cISBN := AllTrim(SELF:oLibri:FIELDGET(#ISBN))
SetDateCountry(ANSI)
DataConsegna := StrTran(dtoc(oDCDatCons:value), ".", "-")
SetDateCountry(ITALIAN)

nProve = 0 // Conteggio delle riprove
cConnAs1 := "call biblioteca.RestituzionePrestito(?, ?, ?);"
DO WHILE TRUE
oSelectAs1 := SQLSelect{cConnAs1, oConnAs1}
oSelectAs1:Execute(NumeroRecord, DataConsegna, cISBN)
IF oSelectAs1:Status = NULL_OBJECT
InfoBox{self, "Informazione:"+ Str(nProve, 2, 0), "La restituzione del testo è avvenuta correttamente"}:Show()
EXIT
ELSE
nProve ++
if nProve < 10
SELF:oSelectAs1:FreeStmt(SQL_DROP)
Aspetta(1.0)
loop
endif
ErrorBox{SELF, "Errore: RetituzionePrestito("+ Str(nProve, 2, 0)+") " + CHR(10) + ;
oSelectAs1:Status:HelpContext + CHR(10) + ;
oSelectAs1:Status:Description + CHR(10) + ;
oSelectAs1:Status:Caption}:Show()
exit
ENDIF
ENDDO
SELF:oSelectAs1:FreeStmt(SQL_DROP)
RETURN NIL

/*----------------------------*/

METHOD Aspetta(nTempo as float)
LOCAL nStart AS FLOAT
LOCAL lContinua := TRUE AS LOGIC

nStart := Seconds()
DO WHILE lContinua
lContinua := (Seconds() - nStart) < nTempo
ENDDO
RETURN NIL

--------------------------------------
Questo è l'errore che mi dava:
[MySQL] [ODBC 8.0(a) Driver][mysql-8.0.18] Commads out of sync; you can't run this command now
nel momento in cui esegue la riga: oSelectAs1:Execute(NumeroRecord, DataConsegna, cISBN)

Come vedete ho dovuto fare un ciclo di tentativi per essere sicuro che eseguisse la SP, e, dalle prove che ho fatto, massimo è arrivato al terzo tentativo.

Il fatto che la stessa transazione con gli stessi parametri viene poi eseguita senza mai un problema su Workbench mi fa pensare che il driver ODBC, forse, dovrebbe essere parametrizzato in maniera più accurata.

Qualcuno può aiutarmi?
Grazie a tutti
Claudio
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Driver ODBC e VO

Post by wriedmann »

Ciao Claudio,
devo premettere che non lavoro con delle stored procedures, e per i progetti attuali ho abbandonato completamente ODBC, perchè mi sono creato delle librerie COM in X# per eseguire le operazioni al database.
Mettendo il messaggio di errore su Dr. Google ho trovato questo risultato:
https://stackoverflow.com/questions/614 ... ommand-now
e questo rispecchia effettivamente quello che stavo pensando.
Se il workbench lo esegue probabilmente perchè usa una connessione apposita.
Vedo due possibilità di risolvere:
- usare una connessione MySQL solo per questa query
- oppure concludere l'operazione eseguita prima, magari con una commit

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
claudiocarletta
Posts: 101
Joined: Sat Sep 05, 2020 8:56 am

Driver ODBC e VO

Post by claudiocarletta »

Ciao Wolfgang,
sempre presente, istantaneo e disponibile, grazie.
- usare una connessione MySQL solo per questa query
Mi hai fatto pensare che forse un controllo del tipo oConnAs1:Reconnect(), non sarebbe male, anche perché, non si vede dal codice che ho postato, ma faccio una query di controllo un attimo prima ed è forse l'unico punto di tutto il programma in cui faccio due accessi a MySQL uno di seguito all'altro con pochissimo codice in mezzo.

- oppure concludere l'operazione eseguita prima, magari con una commit
non credo che serva perché l'accesso a MySQL precedente è solo una SELECT.

A questo punto se il problema è dovuto al fatto che i due accessi sono troppo ravvicinati l'uno all'altro per l'ODBC, la pausa "Aspetta()" che ho messo nel ciclo quasi quasi la metto subito dopo il primo accesso oppure il Reconnect() di cui parlavo prima.

Faccio delle prove e ti faccio sapere
Grazie sempre.
Ciao
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

Driver ODBC e VO

Post by Jamal »

Hi Claudio,

From my experience when updating my MYSql table from VO, use the SQLStatement not SQLSelect.

I tested a quick sample on my system and it was the case.

Try that instead.

Jamal
User avatar
claudiocarletta
Posts: 101
Joined: Sat Sep 05, 2020 8:56 am

Driver ODBC e VO

Post by claudiocarletta »

Grazie Jamal,
avevo provato anche SQLStatement e mi dava lo stesso problema

Ciao
Claudio
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

Driver ODBC e VO

Post by Jamal »

I tried the following and it works fine.

Code: Select all

do while i < 4
	  cQuery := "call library.RientroLibro3(?,?,?)"   
 		
   	   oSqlStatment := SQLStatement{cQuery, oMySqlConnection}   
      
	  ? "statement: ", oSqlStatment:Execute(1, DToCSQL(Today()), "123-4848-4949")   
			
	  oSqlStatment:FreeStmt(SQL_DROP)   

	  i++
 	 wait
			     
enddo 	

May be some settings in your ODBC 32bit connection that you turned on that is affecting the query:

I suggest that you use the code block feature of the editor when pasting code in your posts to make code easy to read your code.

Jamal
User avatar
ArneOrtlinghaus
Posts: 384
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Driver ODBC e VO

Post by ArneOrtlinghaus »

Forse vedi qualcosa se accendi il logging/tracing di ODBC nel ODBC Administrator. Crea velocemente grandi file, ma molto estesi con tutte le informazione che vengono trasmessi. Certi driver trasformano lo statement da sintassi ODBC a sintassi database e magari c'è qualcosa da cambiare. Con Oracle è anche abbastanza complicato eseguire le procedure e dipende da driver la sintassi esatta.

Arne
Post Reply