# Übergabe- Parameter SQL Map



## PollerJava (2. Okt 2007)

Ich hab wie unten, wenn ich statt #tabelle# -> PERSON hinschreibe, dann funktionierts super nur wenn ich den Namen der tabelle mit #tabelle# angeben will, dann bekomme ich wieder mal einen Fehler -> er mag das SQL Statement nicht, was kann ich da machen??


```
<select id="getPerson" parameterClass="sqltest.ReadObj" resultClass="sqltest.Person">   
   SELECT
      PER_ID          as id,
      PER_FIRST_NAME    as firstName,
      PER_LAST_NAME    as lastName,
      PER_BIRTH_DATE    as birthDate,
      PER_WEIGHT_KG    as weightInKilograms,
      PER_HEIGHT_M    as heightInMeters
   FROM #tabelle#       // hier kann ich also den Namen der Tabelle nicht auswählen 
   WHERE PER_ID = #id#
</select>
```







```
Exception in thread "main" com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred in sqlTest/DBXML/Person.xml. 
--- The error occurred while executing query. 
--- Check the        SELECT       PER_ID          as id,       PER_FIRST_NAME    as firstName,
   PER_LAST_NAME    as lastName,       PER_BIRTH_DATE    as birthDate,       PER_WEIGHT_KG    as
weightInKilograms,       PER_HEIGHT_M    as heightInMeters    FROM ?    WHERE PER_ID = ? . 
--- Check the SQL Statement (preparation failed). 
--- Cause: org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544569. Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 205
```





Kann es sein, dass man den Tabellennamen nicht angeben kann???

Ich befürchte schlimmes


----------



## tuxedo (2. Okt 2007)

@PollerJava:
Wenn du doppelt postest wird das Problem nicht doppelt so schnell oder doppelt so gut gelöst.

@alle anderen, siehe:
http://www.java-forum.org/de/viewtopic.php?t=56663&start=30


----------



## PollerJava (2. Okt 2007)

Ja das ist mir klar aber da auf Seite 3 in irgendeinem Thread zu gehen, das will ich euch ersparen,


Wie siehst du das Alex oder an alle, kann ich da noch was anderes machen oder geht das einfach nicht,
wenns nicht gehen würde, dann wäre das sehr viel mehraufwand, da ich eben für jede Tabelle eine XML- Datei brauche,

lg


----------



## tuxedo (2. Okt 2007)

Wäre aber von Vorteil, da man so den Hergang des Problems erkennt (und unter anderem auch das frägwürdige DB-Design ;-) ).

- Alex


----------



## PollerJava (2. Okt 2007)

naja fragwürdiges DB- Design würd ich nicht sagen,
wie würdest du das dann machen , wenn der User aussuchen kann, wieviele Variablen aufgezeichnet werden können,
was ist daran fragwürdig??


----------



## tuxedo (2. Okt 2007)

Wenn der User x-beliebig viele Variablen aufzeichnen kann, dann sollte das in etwa so aussehen:

Tabelle1: Variablen
Spalte 1: Variablen-ID
Spalte 2: Variablenbezeichnung

Tabelle 2: Aufzeichnugen
Spalte 1: Variablen-ID
Spalte 2: Aufzeichnung Wert 1
Spalte 3: Aufzeichnung Wert 2
Spalte 4: Aufzeichnung Wert 3

Etc...

Pro aufzuzeichnende Variable gibt es einen Eintrag in Tabelle 1... Und jede Aufzeichnung, egal von welcher Variable, kommt in Tabelle 2 und ist anhand der ID referenzierbar...

Wenn es auch noch beliebig viele Werte gibt, dann kann man das wieder über eine Tabelle abbilden. 

Eine variable Anzahl an Tabellen ist soweit mir das im studium beigebracht wurde ein schlechtes Design. Und die Praxis zeigt ja gerade wohin sowas führt. Aber da du den roten Faden neu beginnst, müssen die Leute erst den anderen Thread "finden" um zu verstehen.

Vielleicht solltest du dein Vorhaben mit der DB mal genau schildern, dann könnte man ein geeignetes DB-Design finden.

- Alex


----------



## PollerJava (3. Okt 2007)

ja das wäre auch eine Idee, aber was soll ich machen, wenn es mir so vorgegeben ist,

Ich hätte nach deinem Vorschlag dann fiw nur 2 Tabellen aber mit einer unterschiedlichen Zeilenanzahl,

Ich bin mir jetzt noch nicht ganz sicher, ob das dann mit der SQLMap so einfach funktioniert,


Also, wenn ich jetzt 2 Tabellen in meiner Datenbank anlege und wie du oben geschrieben hast die erste Tabelle für die Referenzierung nutze und in der zweiten Dabelle dann die Werte drinnenstehen, dann muss ich aber auch in der 2. Tabelle eine variable Anzahl an Spalten haben, wenn ich das richtig verstehe oder ich mache halt mal auf verdacht eine große Anzahl von Spalten in der 2. Tabelle,


Wäre das Design von der Datenbank dann OK??


lg


----------



## PollerJava (3. Okt 2007)

Wie kann den dann der SQL- Befehl für das hineinschreiben aussehen, wenn ich das DB Desing so wie oben mit 2 Tabellen mache?

Hab noch nie was mit Relationen von Tabellen gemacht!

Bin gerade drauf gekommen, bei mir schauen ja die Tabellen momentan so aus:



TIMESTAMP   |  WERT    -> von diesen Tabellen habe ich z.B.: 5


Wie kann ich die 5 Tabellen in eine Tabelle bekommen??


vielen dank


----------



## PollerJava (3. Okt 2007)

alex0801 hat gesagt.:
			
		

> Wenn der User x-beliebig viele Variablen aufzeichnen kann, dann sollte das in etwa so aussehen:
> 
> Tabelle1: Variablen
> Spalte 1: Variablen-ID
> ...



Hallo Alex,

in meinen Tabellen gehört zu jedem Wert auch ein Zeitstempel, wie könnte ich das machen? Ich würde ja dann in Tabelle 2 den Aufbau so benötigen:


```
Tabelle 2: Aufzeichnugen
Spalte 1: Variablen-ID
Spalte 2: zeitstempel von Wert 1
Spalte 3: Aufzeichnung Wert 1
Spalte 4: zeitstempel von Wert 2
Spalte 5: Aufzeichnung Wert 2
Spalte 6: zeitstempel von Wert 3
Spalte 7: Aufzeichnung Wert 3
```


----------



## PollerJava (3. Okt 2007)

Also ich habs. Man muss den tabellennamen in $tabelle$ geben und nicht in #tabelle#

Ich frag mich jetzt noch, ob ich auf meinem iBatis den DAO aufbauen kann oder ob das 2 verschiedenen Technologien sind,

lg


----------



## tuxedo (3. Okt 2007)

Hast du eine Fixe Anzahl an Werten oder variiert das auch ?


----------



## PollerJava (3. Okt 2007)

Nö, die variiert,

Also ich hab jetzt das Usermanuel gelesen und bin draufgekommen -> das zu lesen zahlt sich auf jeden Fall aus, da erspart man sich eine menge,


Mein Problem bei den Tabellen ist, das die "Zeitstempel | Werte" Paare ser unterschiedlich sein kann (ich zeichne z.B. ein  Werte- Paar alle 2s auf und dass andere alle 5min)

lg


----------



## tuxedo (3. Okt 2007)

Fassen wir also zusammen:

Du hast eine variable Anzahl von "Variablen" und eine variable Anzahl von Werten für die Variablen ...

Sonst noch was?


----------



## PollerJava (3. Okt 2007)

genau, Ich habe eine variable anzahl von Variablen und eine variable anzahl von ZEITSTEMPEL-WERTE paare


z.B.:


```
Temperatur
zeitstempel         wert
12-03-2007          12.322
13-03-2007          14.322
14-03-2007          11.322
15-03-2007           1.322
16-03-2007           2.322
17-03-2007          17.322
18-03-2007          19.322


Leistung 
zeitstempel         wert
12-03-2007           2.322
13-03-2007          54.322
14-03-2007          71.322
```


Also Leistung und Temperatur sind jetzt bei mir 2 Tabellen (Anzahl der Tabellen kann variieren) die unterschiedlich lang sind (Länge (Zeilenanzahl) der Tabellen auch Variabel),

PS:

Falls mal jemand das braucht BETWEEN:

BETWEEN $id1$ AND $id2$


----------



## tuxedo (3. Okt 2007)

Okay... ich fasse nochmal zusammen:

Du hast Variablen...

Pro Variable gibts Werte bezogen auf die Leistung und Werte bezogen auf die Temperatur...

Pro Variable: Läuft die Messung der Leistung und der Temperatur parallel? Sprich: Wird zu einem zeitstempel die Leistung UND Temperatur gemessen. 

Oder laufen die zwei Messungen getrennt?

Sollten sie getrennt laufen, würde die DB wie folgt aussehen:

In meinen Augen sind das 3 Tabellen:

Tabelle 1: Variablen
Spalte 1: Variablen-ID
Spalte 2: Bezeichung der Variablen

Tabelle 2: Temperatur
Spalte 1: Variablen-ID
Spalte 2: Zeitstempel
Spalte 3: Wert

Tabelle 3: Leistung
Spalte 1: Variablen-ID
Spalte 2: Zeitstempel
Spalte 3: Wert

Sollte immer zu einem Zeitpunkt Temperatur UND Leistung gemessen werden, würde die DB so aussehen:

In meinen Augen sind das dann 2 Tabellen:

Tabelle 1: Variablen
Spalte 1: Variablen-ID
Spalte 2: Bezeichung der Variablen

Tabelle 2: Messungen
Spalte 1: Variablen-ID
Spalte 2: Zeitstempel
Spalte 3: Wert Temperatur
Spalte 4: Wert Leistung

Verstehst du was dahinter steckt? In einer Datenbank ist das einzigste was dynamisch ist die Anzahl der Zeilen in einer Tabelle, aber nicht die Tabellen selbst. Du kannst mit diesem Design jederzeit die einzelnen Variablen ausseinander halten und unterscheiden. 

- Alex


----------



## PollerJava (4. Okt 2007)

JA das hab ich verstanden,

NUR:

mein Programm funktioniert momentan so:

Ich habe eine XML- Datei, in der drinnensteht wie mein JFrame aussehen soll, wieviel Panels in dem JFrame drinnen sind (JTabbedPane), wieviel JFreecharts es gibt, welche Komponenten (JButtons, JTextFelder, JBarGraph) auf den einzelnen JPanels drauf sein sollen usw. 

Am jFreeChart kann ich dann variablen auswählen, die ich anzeigen möchte :

siehe: http://www.java-forum.org/de/userfiles/user9898/visu.jpeg

Die Checkboxis mit den Namen links stehen in der *.xml- Datei und werden mit diesem Namen beim ersten mal starten in der Datenbank angelegt also je nach dem welche Variablen und wieviele der User in meinem Designer (muss ich erst schreiben) auswählt, soviel Tabellen werden BEIM ERSTEN STARTEN der Applikation angelegt,

Ich hab also nicht nur Temperaturen und Leistungen sondern das hängt von dem ab, was in der XML- Datei drinnensteht und alle Tabellen in der Datenbank werden zyklisch befüllt und die zeit steht ebenfalls in der Konfigdatei drinnen (das Aufzeichnungsintervall kann der User natürlich auch eingeben z.B.: Temperatur alle 5s aufzeichnen, Leistung alle 500ms aufzeichnen, Lichtstärke alle 20min aufzeichnen -> für das habe ich einen TimerTask), die Messungen laufen also vollkommen getrennt, ich brauche also zu jedem Wert einen Zeitstempel in jeder Tabelle,


So wie ich das jetzt von dir verstanden habe, hab ich ja dann auch wieder eine variable Anzahl von Tabellen, ich weiß ja nicht , wieviele Variblen ausgewählt wurden,

lg und vielen Dank für deine Bemühungen


----------



## tuxedo (4. Okt 2007)

Moin moin....


Sagt dir ERM (Entity Relationship Model) was? Wenn nein könnte dir das hier in Zukunft vielleicht helfen: http://de.wikipedia.org/wiki/Entity-Relationship-Modell

So, aber nun zum eigentlichen "Problem":

Erstmal: Deine GUI sollte absolut unabhängig von deiner Struktur in der Datenbank sein. Für die Abstraktion ist dann das DAO-Entwurfsmuster bzw. auch iBatis zuständig. Soll heißen: Die XMLs für die GUI gehen die Datenbank erstmal nix an. 

So, die Anzahl der Tabellen variablen halten ist nach wie vor "unschönes" Design und sollte vermieden werden.

Bisher hattest du folgenden Entities erwähnt:

1) Variablen
2) Temperatur
3) Leistung

Da du jetzt "damit rausgerückt bist", dass es außer Temperatur und Leistung noch andere Messwerte gibt und du für jede Art von Messwert eine Tabelle haben wolltest, müssen wir das bereits vorgeschlagene Design nochmal überarbeiten.

Ich fang dann mal an:


```
Tabelle 1: Variablen 
Spalte 1: Variablen-ID 
Spalte 2: Bezeichung/Beschreibung der Variablen 
(Spalte 3..n: weitere wichtige Details zur Variablen)

Tabelle 2: Datentyp
Spalte 1: Datentyp-ID 
Spalte 2: Bezeichnung, z.B. "Temperatur", "Leistung" oder sonstirgendetwas in der Richtung 
(Spalte 3..n: weitere wichtige Details zum Aufzeichnungstyp)

Tabelle 3: Messungen
Spalte 1: Variablen-ID (Die Messung gehört zu dieser Variablen ...)
Spalte 2: Datentyp-ID (... und zu diesem Datentyp)
Spalte 3: Zeitstempel
Spalte 4: Wert
```

Mit der Struktur kannst du 

a) beliebig viele Variablen anlegen
b) beliebig viele Datentypen anlegen
c) beliebig viele Messungen bezogen auf Variable und Datentyp in die DB eintragen, zu jedem beliebigen Mess-Zeitpunkt

In diesem Design sind die Datentypen nicht zwingend von der Variablen abhängig. Das hat den Vorteil, dass wenn Variable A und Variable B jeweils "Temperatur" messen, dass es nur einen Eintrag "Temperatur" in der Datentyptabelle geben muss, da in der Messungen-Tabelle die Relation zwischen Variablen und Datentyp hergestellt wird.

Du kannst das auch anders machen:


```
Tabelle 1: Variablen 
Spalte 1: Variablen-ID 
Spalte 2: Bezeichung/Beschreibung der Variablen 
(Spalte 3..n: weitere wichtige Details zur Variablen)

Tabelle 2: Datentyp
Spalte 1: Datentyp-ID 
Spalte 1: Variablen-ID (zu dieser Variablen-ID gehört dieser Datentyp)
Spalte 2: Bezeichnung, z.B. "Temperatur", "Leistung" oder sonstirgendetwas in der Richtung 
(Spalte 3..n: weitere wichtige Details zum Aufzeichnungstyp)

Tabelle 3: Messungen
Spalte 1: Datentyp-ID (zu diesem Datentyp gehört die Messung)
Spalte 2: Zeitstempel
Spalte 3: Wert
```

Welche von beiden Alternativen du dann letztendlich wählst ist dann eine Designfrage. 

- Alex


----------



## PollerJava (4. Okt 2007)

Darf ich nochmal zusammenfassen:

Tabelle3 sieht dann so aus:


```
Var_ID      DT_ID       Timestamp      Wert

 1                 2           12-11-2006         22
 4                 1           11-11-2006         34
 7                 5           08-05-2005         12
usw.
```

Eigentlich super, dann hab ich immer fix 3 Tabellen, 


Es wird halt die Tabelle3 ziemlich lange, ist dass eigentlich unbegrenzt, wie lange eine Tabelle wird (z.B. bei FireBird), also so lange Speicher da ist oder gibts da eine Grenze (z.B.: max. 40000 Zeilen)?

vielen Dank auf jeden Fall für die Erklärungen und die Geduld,

Jetzt muss ich das Design nurnoch durchbringen bei den Verantwortlichen,

lg


----------



## tuxedo (4. Okt 2007)

Die Anzahl der Zeilen ist IMHO nicht derart begrenzt als dass du da schnell Gefahr läufst dass irgendwas überläuft. 

Ich hab Datenbanken die Tabelklen haben in denen ich über 1Mio Zeilen speichere.. Und das sind noch keine wirklich großen Datenbanken. 

Du kannst aber auf Nummer sicher gehen und das Firebird-Handbuch mal konsultieren. Da hast du's dann schwarz auf weiß. 

Eine Fixe Anzahl an Tabellen ist am einfachsten zu warten, zum backupen etc... Gibt genug Gründe das so zu machen.
Eine gute Argumentation wäre im übrigen ein ausgefeiltes ERM-Diagramm das den "einfachen" Aufbau der DB aufzeigt.

- Alex


----------



## PollerJava (4. Okt 2007)

ja von ERM- diagrammen hab ich noch nie gehört, muss mich da mal einlesen,

Das iBatis funktioniert übrigens super!!


lg und danke nochmal,


----------



## tuxedo (4. Okt 2007)

[joke]Die Rechnung kommt dann postwendend[/joke]

Freut mich wenn ich etwas licht in die Sache bringen konnte. 

- Alex


----------



## PollerJava (4. Okt 2007)

Hallo,

Eine Frage hätte ich noch,
wenn ich sehr viele Daten auslese (z.B.: 20000) dann erzeuge ich je auch durch die JavaBean 20000 Objekte und da habe ich schon ein paar mal eine "OutOfMemoryexception Java Heap Space" bekommen,

Was kann ich da dagegen machen, Vor allem habe ich diesen Fehler dann bekommen, wenn ich eine CheckBox (wie auf meinem Bild oben dargestellt) angeklickt habe, dann, obwohl noch keine Kurve da war, wieder angeklickt habe (also weggeklickt) und dann wieder angeklickt habe,

Ich schätze mal, dass da der GC nicht dazukommt, die alten Objekte zu löschen und deshalb der Fehler kommt,

Was meinst du dazu, kann ich da was machen dagegen bzw. wenn ein Java Heap Overflow kommt, kann ich das irgendwie abfangen, sodass es danach ganz normal weiter geht??


----------



## tuxedo (4. Okt 2007)

Es ist halt jetzt die Frage: Brauchst du wirklich 20.000 Objekte gleichzeitig? Wenn du die Daten in den Objekten als Kurve anzeigen willst brauchst du ja nicht 20.000 Werte auf einmal, oder? Du wirst eher immer nur einen Teil der Werte betrachten. D.h. du lädst nur exakt den Teil aus der DB den du wirklich zum anzeigen brauchst. 

Einfach mal alle Daten  zu holen und dann aus dem sammelsurium nur einen Teil für's Zeichnen zu verwenden ist verschenkter Speicher.

- Alex


----------



## PollerJava (4. Okt 2007)

Nö, 
ich hole mir eh nur die Daten, die ich Anzeigen will, alles andere wäre ja Schildbürgerhaft,
Das Problem ist halt, wenn ich (im ExtremFall) 20 Kurven auf dem JFreeChart anzeige und diese alle 500ms aktualisiere, dann hole ich eh nur die Daten aus der DB, welche ich benötige aber das sind dann halt einige,

lg


----------



## tuxedo (4. Okt 2007)

Du kannst der JVM beim Start noch Parameter mitgeben, mit der du den max. Speicherbedarf etwas höher setzten kannst (musst mal hier im Forum suchen oder die Doku zur java(w).exe anschauen. Das wäre der einzigste Ausweg wenn du schon penibel daraiuf geachtet hast, dass du so wenig wie möglich Overhead produzierst.

- Alex


----------



## PollerJava (4. Okt 2007)

Ja das hab ich schon mal gemacht aber es sollte auch so gehen, da ich nicht bei jedem Anwender das einstellen will bzw. das in die bat- Datei schreiben will, aber das bekomme ich schon hin,

Vielen Dank!!!!

lg


----------



## tuxedo (4. Okt 2007)

Wenn du's nicht hochsetzt, dann bleibt dir nur noch das Speicher-Sparen...

Du könntest btw. auch etwas geschickter abfragen, so dass du nicht 20.000 objekte brauchst, sondern die 20.000 Datensätze in einem Objekt stehen.. Hab mir da aber noch keinen Kopf drüber gemacht wie das geht. Aber du würdest ejdenfalls den Objekt-Overhead bei so vielen Objekten sparen.

- Alex


----------



## PollerJava (4. Okt 2007)

Ich hab jetzt noch ein anderes Problem hinzubekommen,

Das mit meinem Tabellenanlegen,

Ich habe vor iBatis abgefragt, ob die Tabelle schon existiert und wenn nicht, dann habe ich diese angelegt:

(If NOT EXISTS geht nicht mit Firebird daher diese unding unten)


```
rs = getConnection().createStatement().executeQuery("SELECT COUNT(RDB$RELATION_NAME) FROM 
RDB$RELATIONS WHERE (RDB$RELATION_NAME = '" + name.toUpperCase() + "') AND RDB$VIEW_SOURCE IS NULL");                     
                    while(rs.next())
                        {
                        tableExist = Integer.parseInt(rs.getString(1));
                        }   
                     if (tableExist == 0)
                        createTable(name);
```

Kann ich das jetzt mit iBatis auch irgendwie machen, die riesen executeQuery wird iBatis ja nicht unbedingt wollen,
gibts da noch eine andere Möglichkeit?

lg


----------



## tuxedo (4. Okt 2007)

Eigtl sollte jede DB irgendeine Variante von IF NOT EXISTS haben... So auch Firefird. Guckst du hier:

http://www.firebirdfaq.org/faq69/

Geht also ohne Java-Code ...
Öfters mal google fragen hilft ungemein ...

- Alex


----------



## PollerJava (4. Okt 2007)

ja das hab ich auch schon gelesen aber soll ich das so in meine *.xml- Daei schreiben?

Nö, habs gerade ausprobiert, es funktioniert nicht:


```
<select id="tabelleExistiert" parameterClass="net.ppos.datenbank.JankDBWertWriteBean" resultClass="net.ppos.datenbank.JankDBWertReadBean">  
		SET TERM !!;
			EXECUTE BLOCK AS BEGIN
				if (not exists(select 1 from rdb$relations where rdb$relation_name = #tabelle#)) then
				execute statement 'create table employee ( id integer );';
			END!!
		SET TERM ; !!
	</select>
```


Fehler:


```
com.ibatis.common.exception.NestedRuntimeException: Error occurred.  Cause: 
com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: 
com.ibatis.common.exception.NestedRuntimeException: Error parsing XPath '/sqlMapConfig/sqlMap'.  Cause: 
com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: org.xml.sax.SAXParseException: Content is not
 allowed in trailing section.

Caused by: org.xml.sax.SAXParseException: Content is not allowed in trailing section.

Caused by: com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: org.xml.sax.SAXParseException: 
Content is not allowed in trailing section.

Caused by: org.xml.sax.SAXParseException: Content is not allowed in trailing section.

Caused by: com.ibatis.common.exception.NestedRuntimeException: Error parsing XPath '/sqlMapConfig/sqlMap'.  
Cause: com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: org.xml.sax.SAXParseException: 
Content is not allowed in trailing section.
Caused by: org.xml.sax.SAXParseException: Content is not allowed in trailing section.


Caused by: com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: org.xml.sax.SAXParseException: 
Content is not allowed in trailing section.
Caused by: org.xml.sax.SAXParseException: Content is not allowed in trailing section.


Caused by: com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: 
com.ibatis.common.exception.NestedRuntimeException: Error parsing XPath '/sqlMapConfig/sqlMap'.  Cause: 
com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: org.xml.sax.SAXParseException: Content is not
 allowed in trailing section.

Caused by: org.xml.sax.SAXParseException: Content is not allowed in trailing section.
```


----------



## tuxedo (4. Okt 2007)

ich würd den Befehl erstmal außerhalb Java mit der DB testen. Und wenn's funktioniert: Was spricht gegen das einfügen in die XML-Map-File? 

- Alex


----------



## PollerJava (4. Okt 2007)

Ausserhalb hats überraschenderweise funktioniert, innerhalb von Java bekomme ich die Fehlermeldung von dem Beitrag um eins vorher.


----------



## tuxedo (4. Okt 2007)

http://www.firebirdfaq.org/faq69/ :


> Those SET TERM statements are only needed if you work from an administration tool like isql or FlameRobin. If you run it from your application code, just send the EXECUTE BLOCK block as a single statement.



Hast du mal den SET TERM kram weggelassen, also in der XML ?

- Alex


----------



## PollerJava (4. Okt 2007)

naja das geht nicht, da die $ im Text drinnensind und das mag iBatis gar nicht bzw. erwartet einen Namen und einen Eintrag in der JavaBean,


EXECUTE BLOCK AS BEGIN
if (not exists(select 1 from rdb$relations where rdb$relation_name = 'EMPLOYEE')) then
execute statement 'create table employee ( id integer );';
END!!
	
	
	
	





```

```


----------



## tuxedo (4. Okt 2007)

*bahnhof*

iBatis ist es doch an und für sich wurscht ob da SET TERM drum rum steht oder nicht? Ist doch DB-Abhängig ...
Und wie kommst du auf "$" ?? Hab bis jetzt meine Variablen immer mit "#" umschlossen, so wie's im Tutorial stand...

-- Alex


----------



## PollerJava (4. Okt 2007)

naja das geht nicht, da die $ im Text drinnensind und das mag iBatis gar nicht bzw. erwartet einen Namen und einen Eintrag in der JavaBean,


```
EXECUTE BLOCK AS BEGIN
if (not exists(select 1 from rdb$relations where rdb$relation_name = 'EMPLOYEE')) then
execute statement 'create table employee ( id integer );';
END!!
```

geht das irgendwie, dass ich nur den ersten Eintrag der Tabellen abfrage und wenn ich was zurückbekomme, dann lege ich nichts an, sonst schon?

wäre das OK??


----------



## PollerJava (4. Okt 2007)

User Manual Seite 33:


```
The database cannot prepare this statement, because it does not know what table will be used. So if you
specify a statement like this:
select * from #tableName#
then you will generally receive an SQLException.
To overcome some of these issues, iBATIS provides syntax for substituting strings into SQL before the
statement is prepared. You can use this support to generate a dynamic SQL statement. An example of the
substitution syntax is as follows:
select * from $tableName$
With this syntax, iBATIS will substitute the value of the “tableName” property into the SQL before the
statement is prepared. With this support, you can substitute string into any part of an SQL statement.
Important Note 1: This support will only substitute Strings, so it is not appropriate for complex data types
like Date or Timestamp.
Important Note 2: If you use this support to alter a table name, or a column list, in an SQL select statement,
then you should always specify remapResults=“true”.
```

Das hat mich einen halben tag gekostet bis ich auf das gestoßen bin!!!


----------



## tuxedo (4. Okt 2007)

Ah, jetzt versteh ich...  okay. iBatis will da also immer stubstituieren wenn ein $ im Statement vor kommt. Und dummerweise muss da ein $ rein um das Statement aus der FAQ zu benutzen... Hmm. Normalerweise müsste sich da doch was maskieren lassen damit iBatis nicht versucht zu substituieren?!


----------



## PollerJava (4. Okt 2007)

Was hältst du von dem, dass ich bei jeder Tabelle den ersten Eintrag abfrage (Wenn das überhaupt geht) und wenn dieser existiert, dann existiert die Tabelle und sonst erzeuge ich diese Tabelle??


----------



## tuxedo (4. Okt 2007)

Naja, ich überlege gerade.. Besonders "sauber" ist das nicht. Hört sich so naxch quick'n'dirty an. 

Da es ja eh nur um das initielle anlegen der 3 Tabellen geht, würde ich, bevor alle Stricke reissen, das ganze in einer statischen methode vor iBatis machen. Allerdings frage ich mich gerade ob iBatis nicht so schlau ist und die Sache mit dem $ erkennt. Weil: 


```
EXECUTE BLOCK AS BEGIN
            if (not exists(select 1 from rdb$relations where rdb$relation_name = #tabelle#)) then
            execute statement 'create table employee ( id integer );';
         END!!
```

Da ist nur ein $ drin.. Wenn du jetzt den Tabellennamen drin haben willst, musst du ja statt #tabelle# einfach $tabelle$ nehmen. Das einzigste weitere $-Zeichen wäre dann in "rdb$relations" ... _Könnte_ gehen.

Auf der anderen Seite:

Manual S. 33


> iBATIS always uses JDBC prepared statements to execute SQL.



Ich weiß nicht ob sich das "krasse" Statement überhaupt in ein Prepared Statement stecken lässt.  Von daher würde ich wohl doch eher zur Lösung außerhalb iBatis greifen. Da es hier ja um einen Sonderfall geht, wäre das wohl noch legitim. 

- Alex


----------



## Guest (5. Okt 2007)

alex0801 hat gesagt.:
			
		

> EXECUTE BLOCK AS BEGIN
> if (not exists(select 1 from rdb$relations where rdb$relation_name = #tabelle#)) then
> execute statement 'create table employee ( id integer );';
> END!!



Es sind leider 2 $ (2 mal rdb$relations)

es sieht das leider als Name 



```
There is no READABLE property named 'relations where rdb' in class 'net.datenbank....[code]
```

Wenn ich es mit einer statischen Methode mache, muss ich eine wieder eine Verbindung zur DB aufbauen usw. und wenn ich dann vielleicht eine andere DB verwende, dann muss ich diesen Code auch wieder anpassen,

Das will ich auf jeden Fall vermeiden,

Vielleicht find ich ja was,


lg
[/code]


----------



## PollerJava (5. Okt 2007)

Ups, der Gast war ich, da hat mir wer den Comp über nacht ausgeschalten und mich ausgeloggt,


----------



## tuxedo (5. Okt 2007)

iBatis wird doch anhand einer Properties-File konfiguriert... D.h. du kannst auch außerhalb von iBatis ein und dieselbe Datenbank benutzen. Und da hier auch Treiber und DB-Url drin enthalten sind bist du super-flexibel und hast nur eine einzige Config für iBatis und deine Tabellen-Erstell-Methode außerhalb iBatis.

- Alex


----------



## PollerJava (5. Okt 2007)

Nö, das versth ich jetzt nicht,

Ich habe eine *.prop, da steht der Driver, Url, name und passwort drinnen und den Pfad zu der xml- Konfig- Datei geben ich so an:


```
String resource = "DBXML/SqlMapConfig.xml";
                Reader reader = Resources.getResourceAsReader(resource);
                sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
```

Wie eben im Tutorial von iBatis,


Ich hab jetzt meine static- Methode so gemacht:



```
try {
            Class clazz = Class.forName("org.firebirdsql.jdbc.FBDriver");   
            }
        catch (Exception e) 
            {            
            fehlerDBDriver.showMessageDialog(null, "Datenbanktreiber konnte nicht gefunden werden", "Datenbank Treiberfehler", 1);
            }
        try {  
            Connection con = DriverManager.getConnection("jdbc:firebirdsql:localhost:c:\\Projekte\viewpanelXML\\FireBird\\TRENDDB.FDB", username, password);
            for (int i = 0; i < Control.getStatesSize(); i++)
                {
                if (Control.getStatesElementAt(i).getTypeElement().equals("TrendVariable") || Control.getStatesElementAt(i).getTypeElement().equals("AlarmeTabelle"))
                    {
                    name = Control.getStatesElementAt(i).getElementName();                                           
                    rs = con.createStatement().executeQuery("SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE (RDB$RELATION_NAME = '" + name.toUpperCase() + "') AND RDB$VIEW_SOURCE IS NULL");                                          
                    while(rs.next())
                        {
                        tableExist = Integer.parseInt(rs.getString(1));
                        }                     
                    if (tableExist == 0 && Control.getStatesElementAt(i).getTypeElement().equals("TrendVariable"))                                                
                        con.createStatement().executeUpdate("CREATE TABLE " + name + "(zeitstempel TIMESTAMP, wert FLOAT)");        
                    else if (Control.getStatesElementAt(i).getTypeElement().equals("AlarmeTabelle"))
                        con.createStatement().executeUpdate("CREATE TABLE " + name + " (Kommen TIMESTAMP, Gehen TIMESTAMP, Quit TIMESTAMP, AlarmNr VARCHAR(16), Var1 INTEGER, Var2 INTEGER)");
                    }                                                                                      
                }                                                         
            }
        catch (Exception io) 
            {       
            fehlerDBDriver.showMessageDialog(null, "Datenbank wurde nicht gefunden", "Datenbank nicht gefunden", 1);                       
            }
```


Du meinst, ich kann die *.prop von iBatis verwenden??

lg


----------



## tuxedo (5. Okt 2007)

Mit einem Property-Reader kannst du die Property von iBatis auslesen. Darin hast du den Treibernamen den du in deiner Static-Method in Zeile 3 einfügen kannst. Die DB-Url aus der Property kannst du in Zeile 10 reinstecken. Ebenso User + PW.


----------



## PollerJava (5. Okt 2007)

Super, funkt..

Danke für die Hilfe,

lg


----------

