# Fehler beim Generierung Fehler beim Generierung java.lang.ArrayIndexOutOfBoundsException: 0



## vikil (12. Mrz 2016)

Hallo zusammen, stehe  auf dem Schlauch, komme nicht drauf.
bekomme Fehler beim Generierung java.lang.ArrayIndexOutOfBoundsException: 0 bei zweitem durchlauf.(rot markiert)
Hat jemand Idee?
Bedanke mich im voraus.


```
public void spGenerierung() {

        String ARG = "";
        String SK = "";
        String ST = "";
        String ZN = "";
        String BMK = "";
        String ANZ = "";
        String SW_Symbol = "";
        String SW_Adresse = "";
        String SW_Datentyp = "";
        String SW_Kommentar = "";
        String AWL = "";

        String M = "1000.0";
        String FC = "14";
        String DB = "2000";
        String Baustein = "14";
        String AWL_TEMP = "";

        try {

            String sql_sp = "SELECT* from SPS WHERE BMK='SP'";
            pst = conn.prepareStatement(sql_sp);
            rs_sps = pst.executeQuery();

            String sql_zuli_vorlage = "SELECT* from ZULI_VORLAGEN WHERE BMK='SP'";
            pst = conn.prepareStatement(sql_zuli_vorlage);
            rs_zuli_Vorlage = pst.executeQuery();

            String sql_temp_vorl = "SELECT* from AWL_VORLAGEN WHERE BMK='SP'";
            pst = conn.prepareStatement(sql_temp_vorl);
            rs_awl_Vorlage = pst.executeQuery();

            pst = conn.prepareStatement("INSERT  INTO ZULI_SW VALUES (?, ?, ?, ?, ? ,?)");

            while (rs_sps.next()) {
                ARG = (rs_sps.getString("ARG"));
                SK = (rs_sps.getString("SK"));
                ST = (rs_sps.getString("ST"));
                ZN = (rs_sps.getString("ZN"));
                BMK = (rs_sps.getString("BMK"));
                ANZ = (rs_sps.getString("ANZ"));

                System.out.println("SPS Tabelle  durchlauf " + ARG + SK + ST + ZN + BMK + " ANZ " + ANZ);


                System.out.println("HHAHAHAH " + rs_zuli_Vorlage.toString());
                SW_Symbol = (rs_zuli_Vorlage.getString("SW_Symbol"));
                SW_Symbol = SW_Symbol.replaceAll("#ARG#", ARG);
                SW_Symbol = SW_Symbol.replaceAll("#SK#", SK);
                SW_Symbol = SW_Symbol.replaceAll("#ST#", ST);
                SW_Symbol = SW_Symbol.replaceAll("#ZN#", ZN);

                SW_Adresse = (rs_zuli_Vorlage.getString("SW_Adresse"));
                SW_Adresse = SW_Adresse.replaceAll("#M#", M);
                SW_Adresse = SW_Adresse.replaceAll("#DB#", DB);
                SW_Adresse = SW_Adresse.replaceAll("#FC#", FC);

                SW_Adresse = (rs_zuli_Vorlage.getString("SW_Adresse"));
                SW_Datentyp = (rs_zuli_Vorlage.getString("SW_Datentyp"));
                SW_Kommentar = (rs_zuli_Vorlage.getString("SW_Kommentar"));

                pst.setString(1, SW_Symbol);<- hier fliegt die Exception  bei zweitem           durch.
                pst.setString(2, SW_Adresse);
                pst.setString(3, SW_Datentyp);
                pst.setString(4, SW_Kommentar);
                pst.setString(5, "0");
                //pst.execute();
                pst.addBatch();

                System.out.println("Zuli Vorlage Tabelle  durchlauf " + SW_Symbol + SW_Adresse + SW_Datentyp + SW_Kommentar);


                System.out.println("HHAHAHAH " + rs_awl_Vorlage.toString());
                AWL = (rs_awl_Vorlage.getString("Inhalt"));
                AWL = AWL.replaceAll("#ARG#", ARG);
                AWL = AWL.replaceAll("#SK#", SK);
                AWL = AWL.replaceAll("#ST#", ST);
                AWL = AWL.replaceAll("#ZN#", ZN);

                System.out.println("Zuli Awl Tabelle  durchlauf " + AWL);
                String sql_awl_gen = "UPDATE FC SET INHALT = REPLACE(INHALT, 'END_FUNCTION', '" + AWL + "') WHERE INHALT like '%END_FUNCTION%';";
                pst = conn.prepareStatement(sql_awl_gen);
                pst.addBatch();
            }
            conn.setAutoCommit(false);
            pst.executeBatch();

            conn.setAutoCommit(true);
            zeitStop = System.currentTimeMillis();
            System.out.println("Verlaufszeit der Schleife für ZULI_HW Import: " + (zeitStop - zeitStart) + " Millisek.");
            dbClose();

        } catch (Exception e) {
            System.err.println("Fehler beim Generierung " + e);
        }

    }
```


----------



## kneitzel (12. Mrz 2016)

Also mir graut es bei diesem Code etwas. Diese Wiederverwendung von Variablen bei entsprechenden Variablennamen ist in meinen Augen extrem unleserlich!
Wieso nutzt Du pst für 3 Queries innerhalb eines Contextes?

Wieso man das nicht machen soll? Weil das einfach nur zu solchen Fehlern führt! Geh den Code mit dem Debugger durch und schau, was in pst für eine Instanz ist, wenn Du da versuchst die Parameter zu setzen! 
(Da wird dann kein Parameter drin sein und daher dann diese Exception!)

Und: Es ist toll, dass Du pst.addBatch() aufrufst. Aber da pst mehrfach neu gesetzt wird, hast du immer neue Instanzen und dann am Ende rufst Du es auf der letzten Instanz das executeBatch auf.

Mal ganz davon abgesehen, dass ich da auch gewisse Bauchschmerzen kriege, wenn Da so parallel mehrere Abfragen gleichzeitig auf der Datenbank laufen. Wobei es da wohl um 3 unterschiedliche Tabellen geht, so dass locking-Probleme wohl nicht zu erwarten sind. Aber ich würde da das Design anzweifeln. Evtl. ist da eine Stored Procedure oder einfach ein SQL Statement besser, so dass da alles in der Datenbank selbst läuft. Eingaben scheint es ja nicht zu geben, so dass es wohl ganz problemlos sein müsste, dass rein per SQL zu bewältigen so dass es nur noch einen einzigen Aufruf geben würde.


----------



## vikil (12. Mrz 2016)

Hallo kneitzel
vielen dank erst mal für deine schnelle Antwort.


> Also mir graut es bei diesem Code etwas. Diese Wiederverwendung von Variablen bei entsprechenden Variablennamen ist in meinen Augem extrem unleserlich


Ja den Code werde ich nich verbessern, war nur zu testzwecken ob es überhaupt so funzt. Variablen namen kommen au der SPS Welt, so heissen da Tabelle Bausteine.


> Wieso nutzt Du pst für 3 Queries innerhalb eines Contextes?


Hast recht ->kann eigentlich mit einer Abfrage den ersten Datensatz ziehen und anhand von diesem Passende Datensätze aus den anderen beiden auf einmal. Oder gibt es bessere Vorgehensweise? Kannst mir vielleicht bitte einen Denkanstoß geben, wie ich in so einem Fall vorgehen soll?




> Und: Es ist toll, dass Du pst.addBatch() aufrufst. Aber da pst mehrfach neu gesetzt wird, hast du immer neue Instanzen und dann am Ende rufst Du es auf der letzten Instanz das executeBatch auf.


 Ok wird auf 1 reduziert.



> Mal ganz davon abgesehen, dass ich da auch gewisse Bauchschmerzen kriege, wenn Da so parallel mehrere Abfragen gleichzeitig auf der Datenbank laufen. Wobei es da wohl um 3 unterschiedliche Tabellen geht, so dass locking-Probleme wohl nicht zu erwarten sind. Aber ich würde da das Design anzweifeln. Evtl. ist da eine Stored Procedure oder einfach ein SQL Statement besser, so dass da alles in der Datenbank selbst läuft. Eingaben scheint es ja nicht zu geben, so dass es wohl ganz problemlos sein müsste, dass rein per SQL zu bewältigen so dass es nur noch einen einzigen Aufruf geben würde.


Hier kommen noch sämtliche abfragen und Entscheidungen hinzu. Wollte DB nur für Daten ablegen und ziehen nehmen. Vielleicht beim nächsten mall, wenn ich mehr Übung darin habe.

Vielen Dank


----------



## kneitzel (12. Mrz 2016)

Also ich habe nicht ganz verstanden, was in den Tabellen steht und so. Und dass Du 3 Select Queries hast, war mir beim durchgehen nicht ganz so interessant wie halt das INERT und UPDATE Query, das Du noch vor bzw. in der Schleife hat (wobei das UPDATE Query in der Schleife dann dafür sorgt, dass du die Parameter nicht setzen kannst).

Wenn die Daten logisch zusammen hängen, dann kann man die Daten zusammen heraus ziehen. Wenn dies nicht möglich ist, dann bleibt es bei 3 Selects (was nicht das Problem ist).

Und um wie viele Datensätze geht es bei den Queries jeweils? Ein typischer Ansatz (da Du mit den Daten ja arbeiten willst) ist immer, das alles ein bisschen zu trennen.
=> Du erstellst Klassen für die jeweiligen Daten. (Aber dabei mitte drauf achten, dass Du die richtigen Typen verwendest. "1000.0" und so sieht verdammt stark danach aus. dass da alles als String abgelegt wurde was so natürlich nicht wirklich eine gute Lösung ist, wenn da nur Zahlen gespeichert werden!)
=> Du erstellst ein Data Layer. Dann hast Du eine Funktion, die die Daten liest und dann halt ausgibt. Also z.B. ein public List<SPS> getSPSs() so SPS die Klasse ist, die die Daten aus der Tabelle SPS repräsentiert.
So Funktionen in der Datenschicht haben immer den gleichen Aufbau:

```
Connection connection;
PreparedStatement statement;
try {
  // Execute Statement
  // Process and return result(s)
} finally {
  if (connection != null) connection.close();
  if (statement != null) statement.close();
}
```
Bzw mit dem neuen try with ressources statt try / finally.

Das hast Du dann für alle Deine Tabellen wo Du es halt brauchst.

Dann hast Du halt einen verkürzten Code:

```
MyDataLayer data = new MyDataLayer(connectionString);
  List<SPS> spsUnits = data.getSPSs();
  List<....> ..... = data.get.....();
  List<....> ..... = data.get.....();
  for (SPS sps: spsUnits) {
    // Do something ..
    data.updateWhatever(dataRequired);
    // ....
    data.insertWhatever(dataRequired);
    // ...
  }
```

So wird dann der Code deutlich übersichtlicher, da alles rund um die low level Datenbankzugriffe entfällt. Bezüglich Business-Logik wirst Du evtl. noch weitere Funktionen und so haben, so dass du eine Funktion mit reinen HighLevel Aktionen hast.

Also die Idee ist dabei, dass man versucht, eine Funktion auf einem Level zuhalten. Ist vergleichbar mit einer Anleitung. Du hast dann eine Anleitung, die auf einem hohen Level geschrieben wurde:
Für jedes Rad wird durchgeführt:
- Rad entfernen
- Rost entfernen
- neues Rad auswuchten
- neues Rad montieren

Das ist dann High Level. Da fängst Du aber dann nicht an, plötzlich bei einem Punkt die exakten Details aufzuschlüsseln. Wer die Details braucht, liest diese dann entsprechend nach.

Was bei einer solchen implementierung aber dann kommt ist: Du hast keinen batch an Anweisungen sondern die Änderungen werden dann erst einmal Stück für Stück ausgeführt wenn es halt aufgerufen wird. (Kann man natürlich auch anders machen, aber das wäre erst einmal die einfache Variante)


----------



## vikil (12. Mrz 2016)

Vielen Dank für die Mühe und investierte Zeit.
Was die Menge von Datensätzen angeht ist unterschiedlich. Kommt auf die Anlage drauf an. Die Software soll auch erweitert werden. Melde mich wenn ich meine Hausaufgabe gemacht habe.  Komme heute nicht dazu, aber will es jetzt auch wissen.
Habe ich es richtig verstanden Klasse(Objekt) mit Instanzvariablen in die der gezogene Datensatz abgelegt wird und mit Funktion geholt,  bearbeitet, und in Tabelle wieder abgelegt wird? 

Vielen Dank, sorry für dumme Fragen, bin ziemlich neu auf dem Gebiet
DANKE


----------



## vikil (12. Mrz 2016)

Kurz zu dem was ich vor habe:
1) es gibt eine Tabelle wo alle Anlogen Komponenten drin sind
2) mir regex ziehe ich die Mänge und anzahl von den Komponenten raus und lege diese in SPS Tabelle ab
3) ich gehe die Datensätze von SPS Tabelle durch und Sammle Daten aus unterschiedlichen Tabellen zusammen(in Datensätzen sind Platzhalter vorhanden) Ersetze die Platzhalter mir richtiger Bezeichnung und lege diese in unterschiedliche Tabellen ab.
Sollte mehr Info benötigt werden, gerne jederzeit.



DANKE


----------



## Sbk Studio (13. Apr 2016)

Um dieses Problem zu beheben, müssen Sie im Programm Argumente oder Befehlszeilen-Argumente übergeben, wenn das Java-Programm ausführen, das Sie erwartet. Abschnitt Weitere Informationen veranschaulicht, wie Programme Argumente unter der IDE angegeben. 

Sie können auch einen Try-Catch-Block um den Code ablegen, die die Programmargumente zugreift. Dieser Code sollte ein ArrayIndexOutOfBoundsException abfangen.


----------



## mrBrown (13. Apr 2016)

try-catch einfach irgendwo rum, um IndexOutOfBounds abzufangen?  Das ist in meinen Augen der alleeschlechteste Lösungsansatz bei solchen Exceptions...

Und warum irgendwelche Befehlszeilen-Argumente übergeben, werden doch überhaupt nicht benötigt^^


----------



## mrBrown (13. Apr 2016)

Ist das Problem denn noch aktuell?


----------



## VfL_Freak (13. Apr 2016)

Moin,


vikil hat gesagt.:


> bekomme Fehler beim Generierung java.lang.ArrayIndexOutOfBoundsException


es stellt sich ja nun erst mal die Frage, WO genau der Fehler auftritt 
ROT MARKIERT sehe ich da im Post schon mal gar nichts !

Also @TO: poste den kompletten Stacktrace und beschreibe ggf. welche Zeile in deinem Code der dort angezeigten Zeile entspricht!!

Gruß Klaus


----------



## kneitzel (13. Apr 2016)

Anstatt da einfach ein try/catch um etwas zu bauen macht es evtl. auch mehr Sinn, einfach die Array-Grenzen vor dem Zugriff abzufragen. Das wäre zumindest für mich die bevorzugte Handlungsweise.


----------



## Harry Kane (14. Apr 2016)

Bin grad mächtig am schmunzeln.
Immerhin ist das Forum sehr responsiv, wenn ein Post von einem Bot in einem seit über einem Monat brachliegenden Thread ausreicht, um 4 Antworten zu bekommen.
Ob die Antworten allerdings zur Lösung des Problems, wenn es denn noch bestünde, beitragen können, wage ich zu bezweifeln.
Die wesentlichen 2 Zeilen deuchen mir die hier zu sein:


vikil hat gesagt.:


> pst = conn.prepareStatement("INSERT  INTO ZULI_SW VALUES (?, ?, ?, ?, ? ,?)");
> pst.setString(1, SW_Symbol);<- hier fliegt die Exception  bei zweitem           durch.


Ich täte mal vermuten dass das PreparedStament von seinem Aufbau nicht zum Aufbau der Tabelle ZULI_SB passt.


----------



## mrBrown (14. Apr 2016)

Die wesentlichen Fehler liegen woanders.
Es funktioniert ja auch beim ersten Durchlauf noch, und erst beim zweiten gehts schief  Außerdem wird da ehh nichts  mit der Tabelle gemacht, sondern nur das PS gefüllt.

Das Problem hätte er gelöst, wenn er obige Vorschläge beachtet hat, deshalb wär's interessant zu wissen, ob es überhaupt nich existiert...


----------

