Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[.Net framework]Vraag over SqlException

Pagina: 1
Acties:

Verwijderd

Topicstarter
SqlException heeft een 'variabele' Errors (een array). Ik probeer uit te vinden onder welke omstandigheden er meer dan een (1) fout kan zijn opgeslagen in deze variabele.

Heeft iemand enig idee hoe dit precies werkt? Onder welke omstandigheden er meer dan een (1) fout wordt opgeslagen in deze variabele? Zoeken op het web heeft (nog) geen antwoord gegeven. Ik wil dit graag forceren om te kunnen testen.

Onderstaand een stukje code waarin het gebruikt wordt.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
        public DataTable execStoredProcedureQuery(string strStoredProcName, Hashtable htParameters, ref string errmsg)
        {
            DataTable tbl = new DataTable();
            try
            {
                using (SqlCommand cmd = new SqlCommand(strStoredProcName, connection))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    if (htParameters != null)
                    {
                        foreach (DictionaryEntry de in htParameters)
                        {
                            cmd.Parameters.AddWithValue(de.Key.ToString(), de.Value);
                        }
                    }
                    tbl.Load(cmd.ExecuteReader());
                }
            }
            catch (SqlException sqlex)
            {
                errmsg = sqlex.Message;
                sqlerrors = new SqlError[sqlex.Errors.Count];
                sqlex.Errors.CopyTo(sqlerrors, 0);
                return null;
            }
            catch (Exception ex)
            {
                errmsg = ex.Message;
                return null;
            }

            return tbl;
        }


Bedankt voor het meedenken.

PS
Zwak punt in bovenstaande code is dat, indien errmsg aan de gebruiker getoond wordt, de structuur van de database gedeeltelijk kan worden bloot gelegd. Ik ben bezig om dat te veranderen.
code:
1
2
Cannot insert duplicate key row in object 'dbo.Decoder' with unique index 'IX_DecoderName'. The duplicate key value is (Explora).
The statement has been terminated.

Verwijderd

Topicstarter
Uiteraard nu het voorbeeld gevonden :(
C#:
1
2
3
4
5
6
7
8
9
10
11
12
        public string getErrors()
        {
            if (sqlerrors == null)
                return null;
            string errmsg = "";

            for (int i = 0; i < sqlerrors.Length; i++)
            {
                errmsg += String.Format("{0}: {1}\r\n", sqlerrors[i].Number, sqlerrors[i].Message);
            }
            return errmsg;
        }


code:
1
2
2601: Cannot insert duplicate key row in object 'dbo.Decoder' with unique index 'IX_DecoderName'. The duplicate key value is (Explora).
3621: The statement has been terminated.


Gezien het resultaat vermoed ik dat het veilig is om alleen de eerste fout te analyseren in de produktie code. Nu nog ongeveer 10000 gebruikers vriendelijke mededelingen proberen te maken :'(

Verwijderd

Ik snap niet waarom dit relevant zou zijn voor je probleem. Een exception hoort niet voor te komen. Je moet niet proberen een exception te vertalen naar een bruikbare melding. Je moet zorgen dat zo'n insert niet voorkomt doordat je vooraf al controleert of iets kan of niet, en daar een zinvolle melding over geven richting eindgebruiker. Er hoort geen mapping te zijn van diep liggende exceptions naar foutmeldingen. Dat zijn de foutmeldingen waar eindgebruikers niets mee kunnen.

Die exceptions moet je gewoon laten loggen naar een foutrapport, en dat moet eigenlijk gewoon nooit voorkomen. Als je een foutrapport krijgt moet je je applicatie zo aanpassen dat je de exception voortaan kunt voorkomen. Dat doe je niet in je databaselaag, maar veel hoger, in het deel van de applicatie dat beter begrijpt wat de eindgebruiker aan het doen is.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
De Message property van de SqlException bevat al de error melding waar je naar op zoek bent.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Lethalis
  • Registratie: April 2002
  • Niet online
Tsja, wie is de "gebruiker" ?

Code zoals in het voorbeeld hoort niet direct in contact te staan met de eindgebruiker in ieder geval. Het ziet er uit als een functie die in een datalaag hoort. Daar bovenop zit je businesslaag en daarna pas de presentatielaag.

Oftewel, als ik het zou opbouwen dan zou de datalaag gewoon de exception throwen zoals hij is en bepaalt de businesslaag wat daarvan aan de gebruiker wordt getoond. Het aantal "gebruiksvriendelijke" meldingen is dan afhankelijk van het proces en dus niet meer generiek. Een melding zou dan bijvoorbeeld zijn "het verwerken van de bestelling is mislukt" als dat een functie zou zijn van mijn business object.

Bouw je namelijk een applicatie die dezelfde "execStoredProcedureQuery" functie gebruikt en je wil in die situatie wel de oorspronkelijke exception afvangen - en dat kan handig zijn met debuggen - dan is het vrij vervelend als je dan "gebruiksvriendelijke" foutmeldingen krijgt.

Afgezien van het feit dat primary key duplicates ueberhaupt niet voor zouden mogen komen bij een goed ontwerp. Soms combineer ik update en insert statements om dat te voorkomen als ik simpelweg iets wil opslaan, als in "eerst updaten, blijkt affected rows 0 te zijn, dan alsnog inserten". Uiteraard wel in 1 transactie (en ik accepteer dan ook dat het eventueel iets overschrijft, als het belangrijke data is check ik altijd eerst en geef ik netjes een melding).

In SQL werk ik ook vaak met autoidentifiers. Op dat moment krijg ik van SQL een volgnummer terug en kan ik dus nooit een duplicate key krijgen. Ook zou je met guid's kunnen werken, omdat die gegarandeerd uniek zijn op dezelfde server.

[ Voor 12% gewijzigd door Lethalis op 24-10-2013 15:25 ]

Ask yourself if you are happy and then you cease to be.