Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    Si può rientrare in una TRY dopo un CATCH?

    Questo è un tarlo che mi rosicchia da tanto.

    In Visual Basic 6 la gestione degli errori era un pò particolare, ma mi dava modo di poter ritornare all'istruzione successiva (o quella che volevo io) dopo aver gestito l'errore a modo mio.

    Tutti ora sputeranno perterra con fare sprezzante e poi diranno "Si, ma si usavano i GOTO, che sono il male!", però io continuo a dire che non era malaccio il sistema, in fin dei conti.

    Ora, essendo passato a C# mi chiedevo questa cosa:

    Nell'eventualità che una determinata operazione nel TRY mi dia errore, nella CATCH, una volta gestito l'errore, posso ritornare all'istruzione successiva a quella che nella TRY mi ha generato l'errore?

    Vi chiedo questo perchè ieri mi sono trovato di fronte a questo problema.

    Avevo un file TXT, era un'esportazione da un DB, ogni riga erano tutti i dati di un record di una tabella, ogni dato aveva il suo spazio.

    Il problema era che deve averlo esportato male e le righe erano doppie, ovvero, per praticamente quasi tutti i record c'erano due righe uguali.

    Facendo una procedura che mi inseriva in una tabella i record incorrevo quasi subito in un errore di chiave primaria duplicata...

    A parte il fatto che potevano gestire meglio il metodo ExecuteNoQuery del Commad (invece di cacciare errore mi cacciava 0 così capivo che qualcosa era andato storto), ma il problema era che alzato l'errore, andava nel catch e saluti a tutti...

    Mi sarebbe tanto piaciutò che, riconosciuto l'errore, potevo ritornare all'istruzione successiva, in maniera tale che poi nella tabella avevo i campi giusti senza duplicati...

    Un metodo efficace srabbe stato fare un select prima di ogni insert, ma avrebbe compromesso la velocità di esecuzione del codice, voi avete suggerimenti?

    Grazie

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,463
    Originariamente inviato da Debiru
    Tutti ora sputeranno perterra con fare sprezzante e poi diranno "Si, ma si usavano i GOTO, che sono il male!", però io continuo a dire che non era malaccio il sistema, in fin dei conti.
    No, non era malaccio.... semplicemente orrendo!

    Originariamente inviato da Debiru
    Nell'eventualità che una determinata operazione nel TRY mi dia errore, nella CATCH, una volta gestito l'errore, posso ritornare all'istruzione successiva a quella che nella TRY mi ha generato l'errore?
    Sì. Basta che tu racchiuda in un blocco try...catch la prima istruzione in cui assorbi l'errore, facendo seguire la seconda istruzione a tale blocco.

    Originariamente inviato da Debiru
    Facendo una procedura che mi inseriva in una tabella i record incorrevo quasi subito in un errore di chiave primaria duplicata...
    Temo che il problema sia dato da un errata stesura del codice da un punto di vista logico, piuttosto che da una qualsiasi limitazione dell'ottimo meccanismo di gestione del codice sfruttando le eccezioni. :master:
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Sì. Basta che tu racchiuda in un blocco try...catch la prima istruzione in cui assorbi l'errore, facendo seguire la seconda istruzione a tale blocco.
    Eh, si, ci avevo pensato, peccato che l'istruzione da eseguire si trovava in un ciclo, e il ciclo doveva continuare con la insert successiva

    Praticamente volevo sfruttare l'errore per saltare nel ciclo la sola istruzione ExecuteNonQuery che generava l'errore...


    Temo che il problema sia dato da un errata stesura del codice da un punto di vista logico, piuttosto che da una qualsiasi limitazione dell'ottimo meccanismo di gestione del codice sfruttando le eccezioni. :master:
    Guarda, non mi chiedere come veniva esportato quel file, perchè neanche lo stesso programma che lo esportava poi era in grado di rileggerlo, sempre per il problema di chiavi duplicate, il programma in questione è una gran bella cloaca, pensa che utilizza il database Pervasive, ma non come database bensì ne sfrutta solo i driver praticamente.

    Infatti non crea un database di sistema, ma in una cartella ha tutti file btr, tab e compagnia bella, grazie al fatto di aver installato sul pc quel dbms puoi navigare in questi file, ma tutte le procedure sono interne al programma, quindi ipoteticamente non puoi neanche metterci le mani SQL parlando...

    Bello eh?

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,463
    Magari potresti postare il codice se vuoi che ci si dia una sbirciatina...
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  5. #5
    Eh, mo non ce l'ho quì ma a casa, vedrò che posso fare, posto solo quel metodo che doveva prendere le righe e metterle nella tabella...

  6. #6
    Come promesso, ecco il codice incriminato:
    codice:
            public void fromTxtToDb()
            {
                String leggi;
                String listino;
                String codice;
                String prezzo;
                String deposito;
                String query;
                Int64 i;
                Int64 k;
                Int64 z;
                i = 0;
                try
                {
                    fin = new StreamReader("f:\\b3listp.txt");
                    Console.WriteLine("Aperto il file in lettura per conteggio righe.");
                    z=0;
                    while (!fin.EndOfStream)
                    {
                        fin.ReadLine();
                        z++;
                    }
                    fin.Close();
                    Console.WriteLine("Numero righe contenute nel file: {0}",z);
                    fin = new StreamReader("f:\\b3listp.txt");
                    Console.WriteLine("Aperto file in lettura per l'elaborazione.");
                    conn.Open();
                    Console.WriteLine("Aperto il database per l'elaborazione.");
                    k=0;
                    while (!fin.EndOfStream)
                    {
                        k++;
                        leggi = fin.ReadLine();
                        listino = leggi.Substring(0, 2);
                        codice = leggi.Substring(2, 50).Replace("'","''");
                        prezzo = leggi.Substring(83, 7);
                        deposito=leggi.Substring(52,4);
                        query = "insert into [blistp-indice](listino,codice,deposito,prezzo) values('" + listino + "','" + codice + "','" + deposito + "'," + prezzo + ")";
                        cmd.CommandText = query;
                        i +=cmd.ExecuteNonQuery();
                        Console.WriteLine("{0}/{1}",k,z);
                    }
                    conn.Close();
                    fin.Close();
                    Console.WriteLine("Righe lette da file: {0}", k);
                    Console.WriteLine("Righe inserite nel DB: {0}", i);
                }
                catch (Exception e)
                {
                    Console.WriteLine("{0}", e.Message);
                }
            }
    Innanzitutto se vedete l'inizializzazione o l'utilizzo di alcune variabili o oggetti non dichiarati è perchè sono globali della classe.

    La tabella su cui va ad inserire è composta dai quattro campi presenti nella insert, dove listino, codice e deposito sono di tipo testo (varchar(2), varchar(50), varchar(4)) e insieme sono chiave primaria della tabella.

    Come vedete c'è un ciclo che serve per leggere tutte le righe del file txt e per ognuno di essi fa elaborazioni e infine esegue una insert...

    Se però la insert genera errore passa alla catch, ma c'è il problema che ho bisogno di continuare con la insert successiva, ovvero il ciclo successivo, e non giova il fatto che termina così l'operazione...

  7. #7
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,463
    Originariamente inviato da Debiru
    Se però la insert genera errore passa alla catch, ma c'è il problema che ho bisogno di continuare con la insert successiva, ovvero il ciclo successivo, e non giova il fatto che termina così l'operazione...
    Se racchiudi la chiamata a ExecuteNonQuery in un costrutto try...catch, dovresti poter fare ciò che vuoi. O mi sfugge qualcos'altro? Ipotizzo osservando in modo - ammetto - molto superficiale il codice (mancanza di tempo).

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  8. #8
    Originariamente inviato da alka
    Se racchiudi la chiamata a ExecuteNonQuery in un costrutto try...catch, dovresti poter fare ciò che vuoi.
    Mmmmhhhhh, ora che mi hai detto così vedo tutto in un'altra ottica, fammi capire, è possibile usare un costrutto simile?

    codice:
    try
    {
        codice;
        codice;
        while(condizione)
        {
            codice;
            try
            {
                codice;
            }
            catch(Exception e)
            {
                codice;
            }
        }
    }
    catch(Exception e)
    {
        codice;
    }
    Sai, purtroppo di esperienza su campo ne ho poca e molte volte vado avanti a culo, ma se mi dici che si può fare una cosa simile oserei dire che è una gran bella cosa e risolverebbe ogni mio problema.

    Ciao!

  9. #9
    Doh, è vero, ho fatto delle rpove e funziona così, si possono annidare le try!

    Ma porc, mannaggia la mia ignoranza, in questo modo è molto più completo il controllo degli errori e posso dire senza ombra di dubbio che frega alla grande la gestione degli errori di VB6!

    Ooohhh, mi si è aperto un nuovo mondo davanti agli occhi

    Tnx Alka!!

  10. #10
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,463
    Sì, puoi ovviamente "annidare" i costrutti di gestione degli errori.

    Il blocco try...catch "assorbe" l'eccezione, quindi se tale blocco è presente, gestisce l'errore che pertanto non ricade nel try...catch più esterno.

    Se vuoi "risollevare" l'eccezione, occorre usare throw.

    codice:
    try
    {
    
        // ...
    
        try
        {
            // ...
        }
        catch
        {
            // Rilancia l'eccezione
            throw;
        }
    }
    catch
    {
        // ...
    }
    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.