Datenbank Statement

Bitte aktiviere JavaScript!
Hallöle

Ich habe eine MS Access DB. Die Verbindung an sich besteht auch.
Ich möchte nun eine SQL Abfrage durchführen. Diese Abfrage steht in einer for-Schleife, weil ich keine Lust habe, 20x den SQL-Befehl umzuändern. Die Werte im int[] kostenstellen sind dann die Einträge, nach denen ich suchen will. Ich bekomme aber immer die unten aufgeführte Fehlermeldung mit "Column not found: 0". Der Spaltenname ist aber KstStNr, so wie er auch in dem SQL-Befehl steht... Weiß jemand ne Lösung??
Später will ich für jede "KstStNr", bestehend aus mehreren WHERE Bedingungen (noch ausgeklammert) die Summe der Werte berechnen und speichern.


Fehlermeldung:

Java:
1. Summe: net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.1 Column not found: 0
    at net.ucanaccess.jdbc.UcanaccessResultSet.getInt(UcanaccessResultSet.java:447)
    at DBConnection.holDbDaten(DBConnection.java:97)
    at Main.main(Main.java:8)
Caused by: java.sql.SQLException: Column not found: 0
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCResultSet.checkColumn(Unknown Source)
    at org.hsqldb.jdbc.JDBCResultSet.getColumnInType(Unknown Source)
    at org.hsqldb.jdbc.JDBCResultSet.getInt(Unknown Source)
    at net.ucanaccess.jdbc.UcanaccessResultSet.getInt(UcanaccessResultSet.java:445)
    ... 2 more
Caused by: org.hsqldb.HsqlException: Column not found: 0
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    ... 7 more
Code:

Java:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class DBConnection {
    
    static Connection connection = null;
    static Statement statement = null;
    static ResultSet resultSet = null;
    
    // 1. Schritt: Oracle JDBC Treiber laden
    
    public static void holDbDaten() {
        
//        Connection connection = null;
//        Statement statement = null;
//        ResultSet resultSet = null;
        
        try {
            Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
        }
        catch (ClassNotFoundException cnfex) {
            
            System.out.println("Problem beim laden des Datenbanktreibers!");
            cnfex.printStackTrace();
        }
        
        
        // 2. Schritt: Öffnen der Datenbank Verbindung
        
        try {
            String msAccDB = "D:"
                    + "/Test.accdb";
            String dbURL = "jdbc:ucanaccess://" + msAccDB;
            
            
            // Step 2.A: Create and 
            // get connection using DriverManager class
            connection = DriverManager.getConnection(dbURL); 

            // Step 2.B: Creating JDBC Statement 
            statement = connection.createStatement();
 
            // Step 2.C: Executing SQL and 
            // retrieve data into ResultSet
            
            int[] kostenstellen = {22854, 24350, 24351, 24352, 24550, 24820, 25330, 26389, 26390, 26391, 26392, 26393, 27139, 27450, 28411, 28470, 28490, 63450, 63500, 63600, 63700, 63800};
//            int[] errechneteSumme = new int[21];

            

            
//            for (int stelle : Summen) {
            
                for (int i = 0; i < kostenstellen.length; i++) {
              
                resultSet = statement.executeQuery("SELECT Betrag FROM Kostenjournal WHERE KstStNr = " + kostenstellen[i]);
  //                      + " (SELECT SUM (Betrag) FROM Kostenjournal WHERE KstArtNr"
  //                      + " = 621100)");
  //              + " = 621100 AND 624100 AND 624200 AND 624300 AND 624400)");
            

            }

           
            // processing returned data and printing into console
            while(resultSet.next()) {
                int z = 1;
                System.out.print(z + ". Summe: ");
                z++;
                System.out.println(resultSet.getInt(0));
                

            }    

        }
        catch(SQLException sqlex){
            sqlex.printStackTrace();
        }
        
        finally {
            // Step 3: Closing database connection
            try {
                if(null != connection) {
                    // cleanup resources, once after processing
                    resultSet.close();
                    statement.close();
 
                    // and then finally close connection
                    connection.close();
                }
            }
            catch (SQLException sqlex) {
                sqlex.printStackTrace();
            }
        } 
    }
}
 
probier es mal mit

getInt("Betrag");

und keine Ahnung von Access aber da gibt es bestimmt auch sowas wie ein IN bei sql

Gruß

Claus
 
Du meinst, in der while Schleife? Bringt nix. Wenn ich z.B. die erste Zahl aus dem int[] nehme, dann ändert sich die Meldung von "0" in die erste Zahl..
 
Danke, dass mit "Betrag" und IN hat hervorragend geklappt.

Nun zu meinem nächsten Problem. Bevor diese Daten in die DB kommen, will ich sie importieren (liegen als CSV vor). Der Import an sich klappt, nur es wird 9x dieselbe Zeile eingetragen...

Hier der Code:

Java:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class CsvIntoDb extends DBConnection {


public static void load() throws IOException, ClassNotFoundException, SQLException {
    String sql = " INSERT INTO Kostenjournal (AbrKr, AbrJahr, AbrMon, KstStNr, KstStBez, KstArtNr, KstArtBez, Std, Betrag) VALUES(?,?,?,?,?,?,?,?,?) ";


    try {
            BufferedReader bReader = new BufferedReader(new FileReader("D:\\csv.csv"));
            String line = "";
            while ((line = bReader.readLine()) != null) {
                try {

                    if (line != null)
                    {
                       
                        String[] array = line.split(";+");
                        for(String result:array)
                        {
                            System.out.println(result);
                           
     //Create preparedStatement here and set them and excute them
                           
                            preparedStatement = connection.prepareStatement(sql);
                            preparedStatement.setString(1, array[0]);  
                            preparedStatement.setString(2, array[1]);
                            preparedStatement.setString(3, array[2]);
                            preparedStatement.setString(4, array[3]);
                            preparedStatement.setString(5, array[4]);
                            preparedStatement.setString(6, array[5]);
                            preparedStatement.setString(7, array[6]);
                            preparedStatement.setString(8, array[7]);
                            preparedStatement.setString(9, array[8]);

                                                                   
                            preparedStatement.executeUpdate();
                            preparedStatement.close();
                           
       //Assuming that your line from file after split will folllow that sequence

                        }
                    }
                }
                finally
                {
                   if (bReader == null)
                    {
                        bReader.close();
                    }
                }
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
    }
}

Irgendwas hab ich da verkehrt gemacht, weiß nur nicht was
 
Zuletzt bearbeitet:
Irgendwas hab ich da verkehrt gemacht, weiß nur nicht was
Naja, Du iterierst über das Array und fügst somit für jede Spalte Deine setStrings aus: macht 9 Stück.

Probiers mal so:

Java:
public static void load() throws IOException, SQLException {
    String sql = " INSERT INTO Kostenjournal (AbrKr, AbrJahr, AbrMon, KstStNr, KstStBez, KstArtNr, KstArtBez, Std, Betrag) VALUES(?,?,?,?,?,?,?,?,?) ";

    try(PreparedStatement stmt = connection.prepareStatement(sql);
            BufferedReader bReader = new BufferedReader(new FileReader("D:\\csv.csv"))) {
        String line;
        while ((line = bReader.readLine()) != null) {
            String[] array = line.split(";+");
            for (int i = 0; i < array.length; i++) {
                stmt.setString(i+1, array[i]);
            }
            stmt.addBatch();
        }
        stmt.executeBatch();
    }
}
EDIT: noch ein paar Korrekturen am Code vorgenommen.
 
Guten Morgen

Vielen Dank! Das passt super.

Die erste Zeile enthält Spaltennamen, welche ich bereits in der DB selber übernommen habe. Wie kann ich den Algorithmus so anpassen, dass er in der zweiten Zeile beginnen soll?
 
Na die erste Zeile einfach ignorieren, z.B. entweder mit ner Bedingung in der Schleife oder aus der Schleife zeihen.
 
Ja, wenn Du weißt, dass die Datei immer wenigstens einen Header hat, dann füg einfach bReader.readLine(); vor der Schleife ein.
 
Ja, wenn Du weißt, dass die Datei immer wenigstens einen Header hat, dann füg einfach bReader.readLine(); vor der Schleife ein.
Dankeschön.

Ich habe jetzt ein anderes Problem.
Die CSV Datei enthält int und String Daten. In meinem Code habe ich ja die String[] array zum lesen stehen.
Wenn ich die Spalten in der DB als Text einstelle, klappt das importieren. Aber so kann ich ja nicht mit den Zahlen arbeiten, wenn die als Text in der DB eingespeichert sind. Wenn ich die Spalten in der DB passend zu der einzulesenden csv einstelle, dann klappt der import nicht. Es kommt dann folgende Fehlermeldung:

Java:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.1 data exception: invalid character value for cast
    at net.ucanaccess.jdbc.UcanaccessPreparedStatement.setString(UcanaccessPreparedStatement.java:701)
    at CsvIntoDb.load(CsvIntoDb.java:23)
    at GUI$2.actionPerformed(GUI.java:62)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown 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.mouseReleased(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(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown 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.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.sql.SQLDataException: data exception: invalid character value for cast
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.throwError(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.setParameter(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.setString(Unknown Source)
    at net.ucanaccess.jdbc.UcanaccessPreparedStatement.setString(UcanaccessPreparedStatement.java:699)
    ... 38 more
Caused by: org.hsqldb.HsqlException: data exception: invalid character value for cast
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.Scanner.convertToNumber(Unknown Source)
    at org.hsqldb.types.NumberType.convertToType(Unknown Source)
    ... 41 more

Ich hatte mir dann überlegt, die DB Spalten als String stehen zu lassen und dann noch eine zusätzliche Klasse zu erstellen, in der ich die Datentypen in der DB caste bzw. konvertiere... was aber nicht funktioniert.

Java:
import java.sql.SQLException;

import javax.swing.JOptionPane;

public class Converter extends DBConnection {
   
    public static void convert() {
       
        try {
//            resultSet = statement.executeQuery("SELECT CAST((AbrKr, AbrJahr, AbrMon, KstStNr, KstArtNr, Std, Betrag) AS INT) FROM Kostenjournal");
            resultSet = statement.executeQuery("SELECT CONVERT(int(10), Betrag)) FROM Kostenjournal");
           
// Syntax:        SELECT CONVERT(varchar(10), field_name) FROM table_name
           
            JOptionPane.showMessageDialog(null, "CASTEN erfolgreich!");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            JOptionPane.showMessageDialog(null, "CASTEN nicht erfolgreich!");
            e.printStackTrace();
        } finally {
            try {
                resultSet.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                JOptionPane.showMessageDialog(null, "Fehler beim schließen des RESULTSET in der Klasse Converter!");
            }
        }
       
       
    }

}
Für das unausgeklammerte ResultSet (da wollte ich probehalber nur eine Spalte umwandeln) im Code hier drüber kommt dann diese Fehlermeldung:
Java:
UCAExc:::4.0.1 type not found or user lacks privilege: BETRAG
Für den ausgeklammerten resultSet kommt:
Java:
UCAExc:::4.0.1 java.lang.NullPointerException java.lang.NullPointerException
 
Zuletzt bearbeitet:
Aber so kann ich ja nicht mit den Zahlen arbeiten, wenn die als Text in der DB eingespeichert sind. Wenn ich die Spalten in der DB passend zu der einzulesenden csv einstelle, dann klappt der import nicht. Es kommt dann folgende Fehlermeldung:
Das sollte eigentlich nicht sein. Wenn Du per setString eine Zeichenkette angibst, die eine Zahl enthält, dann sollte das automatisch umgewandelt werden.

Das scheint auch versucht zu werden:
Caused by: java.sql.SQLDataException: data exception: invalid character value for cast
Kann es sein, dass die Reihenfolge der eingelesenen Spalten mit denen der importierten nicht zusammenpasst und somit eine ganz andere Zeichenkette auf eine int-Spalte abgebildet wird?
 
Das sollte eigentlich nicht sein. Wenn Du per setString eine Zeichenkette angibst, die eine Zahl enthält, dann sollte das automatisch umgewandelt werden.

Das scheint auch versucht zu werden:

Kann es sein, dass die Reihenfolge der eingelesenen Spalten mit denen der importierten nicht zusammenpasst und somit eine ganz andere Zeichenkette auf eine int-Spalte abgebildet wird?
Habe es grade nochmal geprüft, passt eig..

CSV: Zahl | Zahl | Zahl | Zahl | Text | Zahl | Text | Zahl | Zahl
DB: Zahl | Zahl | Zahl | Zahl | Text | Zahl | Text | Zahl | Zahl

Wobei mir grade aufgefallen ist, dass die letzte Stelle in der CSV eine Währung bzw. Gleitkommazahl ist.. in der DB hab ich die dazugehörige Spalte aber nur als INT deklariert. Hab grad mal als Währung versucht da es auch tatsächlich eine Währung darstellt, aber es kommt dieselbe Fehlermeldung.


EDIT:

In der Klasse "Berechne" greife ich nämlich auf die Beträge (letzte Spalte) zu mit
Java:
          resultSet = statement.executeQuery("SELECT SUM (Betrag) FROM Kostenjournal WHERE KstStNr IN (" + kostenstellen[i] + ")"
                  + "AND KstArtNr IN (621100, 624100, 624200, 624300, 624400)");
Ich führe zuerst den Import durch, was an sich klappt (wenn ich die Klasse Converter nicht aufrufe), aber wenn ich dann die Klasse Berechne aufrufe, kommt eben auch diese Fehlermeldung:
Java:
UCAExc:::4.0.1 incompatible data type in operation
Die Klasse Berechner funktioniert. Das habe ich geprüft gehabt, in dem ich die CSV manuel in die DB eingepflegt hatte. Da waren dann aber auch die Spaltentypen richtig. Hier habe ich jetzt ja alle Spaltentypen auf String stehen. Deswegen rechnet er ja auch nicht. Daher wollte ich halt die Spaltentypen nach dem Import casten/konvertieren...
 
Zuletzt bearbeitet:
Guten Morgen
Habe ich probiert, es kommt dieselbe Fehlermeldung.

Aber wieso klappt das casten denn nicht..? Die Datentypen müssen geändert werden..
 
K

kneitzel

Zu #11 noch einmal:

Also ich weiß nicht so recht: Du hast ja eine Access Datenbank unter drunter. Da ist eine erste Frage, ob er so Dinge wie CONVERT überhaupt so kennt. Evtl. sieht die Funktion anders aus oder eben eine andere Funktion müsste benutzt werden. CInt und so kennt Access meiner Meinung nach. Aber ob das rein VB ist oder auch in die Datenbankabfragen rein läuft, das kann ich nicht sagen.

"Type not found: BETRAG" (verkürzt dargestellt) scheint zu bedeuten, dass er da Dein BETRAG als Typ angesehen hat...
Aber die Abfrage ist auch nicht stimmig: SELECT CONVERT(int(10), Betrag)) FROM Kostenjournal
2x "(", 3x ")" - so kann es nicht klappen....
Die Cast Anweisung mit mehreren Feldern kommt mir auch etwas dubios vor. Da hätte ich pro Feld ein Cast erwartet....
 
Hast Recht, sowas wie "SELECT CONVERT(int(10), Betrag)) FROM Kostenjournal " funktioniert nicht. Es muss so eine Syntax sein:

ALTER TABLE table_name
ALTER COLUMN column_name datatype

So funktioniert es auch für alle Spalten! Nur eine nicht :D nämlich für die letzte, Betrag...

Betrag ist z.B. 806,03...
Das kann man so ohne weiteres nicht von einem String in einen integer umwandeln, weil das Komma dort zu diesen Fehlern führt!
Habe es mit decimal, currency, money versucht, gehen alle nicht :rolleyes:
 
Oder evtl. einmal das "," durch "." ersetzen und dann probieren.
Dann wandeln sich manche Beträge in der CSV in ein Datum um..
Float klappt auch nicht leider. "25,6" wird dann zu 25.Jun

Java:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.1 data exception: invalid character value for cast in statement [ALTER TABLE Kostenjournal
ALTER COLUMN Betrag float]
 
Passende Stellenanzeigen aus deiner Region:

Oben