Q & A

Questo spazio è dedicato alla risoluzione dei vostri problemi di programmazione. Proponete domande tecniche ed otterete risposte pratiche ed esaustive ai vostri questi.

q&a@infomedia.it

Transazioni VB con Oracle

Salve mi chiamo Andrea e volevo porvi una domanda se è possibile: per gestire le transazioni su un Db con Visual Basic attraverso il motore ADO utilizzo il seguente listato:

Public Sub Esegui()
    Connn.BeginTrans
    ssql = "INSERT INTO UTENTI VALUES (1, 'PIPPO', 'PIPPO')
   
conn.Execute(ssql)

    ssql = "INSERT INTO TRACK_LOG VALUES ('CREAZIONE UTENTE PIPPO')
    conn.Execute(ssql)

    conn.CommitTrans
End Sub

Quindi sia su Access che su SQL Server 7.0 finché non esegue la CommitTrans i dati non vengono scritti fisicamente sul db e se eseguo una RollbackTrans al posto della commit il db mi annulla l'inserimento che ho fatto; con Oracle versione 8.04 invece ho notato che anche se eseguo la RollbackTrans lui mi fa ugualmente la prima "INSERT INTO Utenti ...", quindi è come se mi facesse un'auto Commit della prima istruzione e la rollback della seconda istruzione "INSERT INTO Track_log ...".
La domanda che vorrei porvi è la seguente come posso eseguire la rollback correttamente e quindi annullare le due insert eseguite naturalmente togliendo l'istruzione conn.CommitTrans e sostituendola con conn.RollbackTrans come nell'esempio qui sotto?

Public Sub Esegui()
    conn.BeginTrans

    ssql = "INSERT INTO UTENTI VALUES (1, 'PIPPO', 'PIPPO')
    conn.Execute(ssql)

    ssql = "INSERT INTO TRACK_LOG VALUES ('CREAZIONE UTENTE PIPPO')
    conn.Execute(ssql)

    conn.RollbackTrans
End Sub

Perché con Access e SQL Server mi funziona e quindi annulla le due INSERT e con Oracle no? C'è qualche settaggio particolare di Oracle che non va? Spero che la mia domanda sia stata chiara.
In attesa di una vostra risposta colgo l'occasione per ringraziare tutti quanti del materiale molto interessante che mettete in rete.

Andrea D'Angelo

Risponde Davide Quack

Conosco male Oracle ma credo di poterle dare delle indicazioni utili per la risoluzione del suo problema. Devo però innanzi tutto correggerla. L'esecuzione di transazione non vuol dire che i dati non sono scritti fino al commit, ma che è possibile annullare le modifiche in caso di rollback. Sembra una distinzione di lana caprina, ma in un ambiente concorrente, o se si fa uso di trigger, questa differenza è vitale.
Guardando il suo codice presumo che la connessione con Oracle ha impostata la terminazione della transazione implicita, oppure che l'apertura della transazione attraverso il driver è bacata.
Per verificare la seconda ipotesi può provare ad iniziare la transazione attraverso la query stessa, con la classica "BEGIN TRANSACTION" in testa alla query. La verifica della prima ipotesi è più complicata. Personalmente uso da tanti anni, con soddisfazione, ODBC. Le consiglio quindi di provare a fare il suo esperimento utilizzando i driver ODBC e un DSN. Questo perché se crea un DSN sono certo che può controllare tutti i parametri della connessione, tra cui la famigerata opzione di esecuzione con commit automatico.
Saluti

 

 

Assembly e moduli .NET

Gentile Alberto Falossi,
mi sto avvicinando al mondo .NET ma non ben chiara la differenza tra un modulo e un assembly. La documentazione a corredo del .NET Framework SDK non è molto chiara, mi può aiutare lei? Se è possibilre compilare del codice in moduli invece che assembly, qual è la differenza?
Distinti saluti

Giacomo V.

Risponde Alberto Falossi

Si può pensare ad un assembly come un EXE o una DLL logica in .NET. Un assembly è identificato da un nome e una versione come avviene per i componenti COM. La definizione di "eseguibile logico" è dovuta al fatto che un assembly non è necessariamente una singola entità ma al suo interno può essere formato da vari moduli.
Un modulo è un file che contiene codice IL e metadati ma per essere eseguito deve far parte di un assembly: una situazione analoga si ha per i moduli oggetto "classici" che, pur contenendo codice e dati, devono essere uniti (con il linker) in un eseguibile.
Grazie ai moduli si possono riunire spezzoni di codice scritti in linguaggi differenti in un unico assembly. Il manifesto (manifest) dell’assembly che elenca i file che lo costituiscono, i tipi definiti e le dipendenze da altri assembly.
In C# si può scegliere se compilare i sorgenti in un modulo o in un assembly grazie al parametro t (target) del compilatore:

csc /out:MyApp.exe /t:module MyApp.cs

csc /out:MyApp.exe /t:exe MyApp.cs

Nel primo caso MyApp è compilato in un modulo che, anche se ha estensione exe, non può essere eseguito (sarà visualizzato "MyApp.exe is not a valid Win32 application"). Nel secondo caso MyApp.exe è un assembly e può essere eseguito normalmente.
Per unire più moduli in un assembly si possono usare il compilatore (opzione addmodule di csc) o l’utility AL.EXE (Assembly Linker) del .NET Framework SDK.
Saluti.

 

 

Problemi con l'uso della Wscript.shell

Il mio problema è il seguente: lavoro con due PC Windows NT 4.00, su entrambi è installato Visual Studio 6.0 ma stranamente solo su uno dei due la funzione Wsript.shell richiamata in un programma Visual Basic funziona, quindi vorrei sapere quale libreria, o altro, si porta dietro la Wsript. Avrei una certa urgenza per cui le sarei grata se potesse darmi una risposta nel più breve tempo possibile.
La ringrazio anticipatamente

Barbara Stefano

Risponde Dino Esposito

Probabilmente solo su uno dei due è installato il WSH che non è standard su tutte le versioni SP di NT4. Verifica se ci sono wscript.exe e wshom.ocx. Se WSH non è installato correttamente scarica il file setup da http://msdn.microsoft.com/scripting/.

 

 

Problemi con il Data Control di VB

Spett/le Signor Falossi,
mi cimento da poco con il Visual Basic, ed in particolare con il controllo Data.
Il mio problema è il seguente: ho costruito una form su cui ho posto i vari controlli che dovranno visualizzare i vari dati presenti nel database (Access 97), ammettendo anche l'inserimento di nuovi dati, e naturalmente il controllo Data associato al file access. Su questa form ci sono anche alcuni DBCombo che permettono delle scelte in base al contenuto di un altro file access (ma penso che non c'entri molto). Quando però vado ad eseguire il metodo dbArchivio.Recordset.AddNew, e voglio quindi creare un nuovo record, Visual Basic mi dà un errore stranissimo: "Errore di run-time '3426': Azione eliminata da un oggetto associato". Non riuscendo a capire cosa significhi, se provo a premere il pulsante con il "?" per chiedere l'Help, MSDN mi risponde che l'argomento non esiste (devo dire che ho il Visual Studio 6.0)! Andando ad intuito potrei pensare che c'è qualche "azione di disturbo" di qualche controllo associato al controllo Data, ma come faccio a capire quale controllo è, e soprattutto cos'è che dà fastidio???
La ringrazio molto e confido in una sua risposta. Sto lavorando ad un progetto e non mi riesce di andare avanti per questo errore, che non so assolutamente come gestire.
Cordiali saluti,

Pierfrancesco Zicarelli

Risponde Alberto Falossi

L'errore si presenta perché quando si esegue AddNew(), VB tenta di salvare il recorset attualmente puntato dal data control. Probabilmente nel suo caso il data control sta puntando a NULL, non a un recorset empty. Mi sembra di ricordare che se si effettua un controllo sulle proprietà BOF o EOF (con If) prima di aggiungere un record il problema non si verifica. Altrimenti credo basti far puntare il data control a un elemento consistente del db.
Saluti.