Volledige versie bekijken : probleem in java( odbc-jdbc



spitfiresoul
20 December 2009, 14:14
ik werk momenteel aan een taak die ik moet afhebben voor mijn examen java programeren.

nu een onderdeel van de taak houd in dat we met een databaseconnectie moeten werken wat we dus nog maar 1 keer in het verleden hebben moeten doen. als gevolg zal het volgende stukje code mss niet echt goed geschreven en omslachtig overkomen dus zou ik tips hierop ook zeker apprecieren maar als jullie me al voorbij deze fout zouden kunnen helpen zou ik al heel dankbaar zijn.


eerst wat informatie. de methode waar ik een exception op krijg dient om de gegevens van een klant te wijzigen op basis van de naam van die klant.
het "moeilijke hieraan is dat de naam, voornaam, nr en adresnr van die klant in de tabel klanten zit en het adres( met als link dus adresnr naar adresid) zit in een andere tabel.

ik moet dus op 1 of andere manier eerst de voornaam van de klant aanpassen. vervolgens op basis van de familienaam het veld adresnr ophalen om vervolgens dit te gebruiken in een nieuwe updatequery om het juiste adres aan te passen.


ik ben voorlopig op deze manier te werk gegaan. het lijk mij wat omslachtig maar bij gebrek aan echt goede voorbeelden of ervaring probeer ik me wel te redeen:

public void wijzigKlant(String naam, String voornaam,String straat, int nr, String postcode, String gemeente )
{
Connection con = null;
try{
con = DatabankConnectie.getInstance().getConnection();
con.setAutoCommit(false);
PreparedStatement select = con.prepareStatement("select Adresnr FROM klanten WHERE naam = ?");
select.setString(1, naam);
PreparedStatement prepStat = con.prepareStatement("update klanten set voornaam = ? where naam = ?");
PreparedStatement prepStat2 = con.prepareStatement("update adres set straat = ?, nr = ?, postcode = ?, gemeente = ? where refnr = ?");
ResultSet id = select.executeQuery();
prepStat.setString(1,voornaam);
prepStat.setString(2,naam);
prepStat2.setString(1,straat);
prepStat2.setInt(2,nr);
prepStat2.setString(3,postcode);
prepStat2.setString(4,gemeente);
prepStat2.setInt(5,id.getInt(1));


prepStat.executeUpdate();
prepStat2.executeUpdate();
con.commit();
}catch(SQLException e){
try {
con.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
con.setAutoCommit(true);
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}

}
}

de exception die ik hierbij krijg is deze:

: [Microsoft][ODBC-stuurprogrammabeheer] Ongeldige cursorstatus
at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.SQLGetDataInteger(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getDataInteger(Unk nown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getInt(Unknown Source)

at DatabankKlant.wijzigKlant(DatabankKlant.java:85)
at Guitaak$3.actionPerformed(Guitaak.java:105)

at javax.swing.AbstractButton.fireActionPerformed(Unk nown Source)
at javax.swing.AbstractButton$Handler.actionPerformed (Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed (Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseRe leased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent( Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(U nknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unkno wn Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilter s(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(U nknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarch y(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)


de fout krijg ik dus op lijn 85 waar ik dus de methode id.getInt(1) oproep.

het kan zijn dat ik er gewoon overkijk maar na toch al redelijk wat dingen te hebben uitgeprobeerd heb ik toch besloten om even hier hulp in te roepen.

in geval dat het iets uitmaakt:
de tabel klanten bevat: id(keyveld) naam, voornaam en adresnr
de tabel adres bevat adresnr(key), straat, nr, postcode en gemeente

alvast bedankt

ultddave
20 December 2009, 14:46
De fout:
[Microsoft][ODBC-stuurprogrammabeheer] Ongeldige cursorstatus

Is meestal gelinked aan database fouten (Hiermee bedoel ik dat je een actie uitvoert die niet mogelijk is op query ofzo :D).
PS: Dat lijkt toch alleszins zo, als je alle google resultaten bekijkt :D
http://www.google.be/search?hl=nl&source=hp&q=Ongeldige+cursorstatus&meta=&aq=f&oq=


Waarschijnlijk zal er iets fout zijn bij die:
id.getInt(1)

Best kan je eens debuggen en dan kijken bij die regel wat hij precies doet, en wat de waarde is van die variabele na die instructie. ;)

Mvg,
Dave

spitfiresoul
20 December 2009, 23:04
De fout:
[Microsoft][ODBC-stuurprogrammabeheer] Ongeldige cursorstatus

Is meestal gelinked aan database fouten (Hiermee bedoel ik dat je een actie uitvoert die niet mogelijk is op query ofzo :D).
PS: Dat lijkt toch alleszins zo, als je alle google resultaten bekijkt :D
http://www.google.be/search?hl=nl&source=hp&q=Ongeldige+cursorstatus&meta=&aq=f&oq=


Waarschijnlijk zal er iets fout zijn bij die:
id.getInt(1)

Best kan je eens debuggen en dan kijken bij die regel wat hij precies doet, en wat de waarde is van die variabele na die instructie. ;)

Mvg,
Dave

hij geeft idd de fout voledig bij het id.getint.

dus als ik de waarde die ik uit de database haal probeer te zien dmv een println ofzo dan krijg ik daar de exception ook. dus op 1 of andere manier kan hij die waarde niet uit de databank halen. waarom weet ik niet.

en verder als ik dit stukje code:
PreparedStatement select = con.prepareStatement("select Adresnr FROM klanten WHERE naam = ?");
select.setString(1, naam);

vervang door:
PreparedStatement select = con.prepareStatement("select Adresnr FROM klanten WHERE naam = "+ naam);

dan krijg ik een andere fout: ook sql maar deze keer is het dan
niet voldoende parameters, aantal verwachte parameters: 1

carl
21 December 2009, 23:11
In je laatste voorbeeld stel je je code kwetsbaar op voor SQL injection, het is beter om te werken met een PreparedStatement.setXXX(count, variabele). Je gebruikt daarvoor in je preparedstatement een '?' waar een variabele komt (die worden dan genummerd -> count)

Het lijkt me in feite ook geen slecht idee om je code die je nu hebt in commentaar te plaatsen en vanaf 9 te herbeginnen. Even men bedenkingen:


de gegevens van een klant te wijzigen op basis van de naam van die klant.
het "moeilijke hieraan is dat de naam, voornaam, nr en adresnr van die klant in de tabel klanten zit en het adres( met als link dus adresnr naar adresid) zit in een andere tabel.

Je moet je, als je werkt met een database goed afvragen wat er mogelijk is. welke gegevens dienen hier juist aangepast te worden ?
ELKE methode die zaken aanpast moet in principe met 100% zekerheid weten welke record hij moet gaan aanpassen, dwz dat hij moet een primaire sleutel, of een andere unieke identificatie meekrijgen. (geen gedoe met dubbele records, niet bestaande records, ...).
Dus moet het als volgt gebeuren:
gewijzigde gegevens zijn beschikbaar->opzoeken van geschikte gebruiker-> doorvoeren van wijziging op gebruiker

Het lijkt mij dus echt niet moeilijk om data over 2 verschillende tabellen aan te passen ? Die tabel met adressen zal immers een relatie hebben met die van de namen, en dus een sleutel bevatten.

Ongeldige cursorstatus betekent dat je query leeg is, of dat je de .next() methode nog niet hebt aangeroepen.
Aantal verwachte blabla betekent dat er iets loos is met je SQL statement.

Ik geloof dat er ook iets mis sis met je database, wat is het adresnummer juist ? Kan je anders even je relationeel model of (E)ERD posten ?
Je werkt ook met meerdere statements op 1 connectie wat ook niet echt een goed idee is, het zou beter zijn als je database wat beter aangemaakt is en je het zoeken van de juiste gebruiker.
Er zijn dus een paar zaken die ik me afvraag;
- waarom gebruik je in de tabel met adressen in godsnaam niet het "refnr" (=primaire sleutel) ? Het kan ook op jouw manier maar je maakt het jezelf alleen maar moeilijker.
- waarom niet alle gegevens in 1 tabel ? Het adres kan je toch zien als een attribuut bij de entiteit klant ? (tenzij 1 klant meerdere adressen kan hebben, maar daar zou je dan al moeten rekening mee houden in je code).
- werk je met threads ? (Guitaak$3.actionPerformed(Guitaak.java:105))