# SQL-Blockbefehl / Script



## entegutallesgut (9. Aug 2007)

Hallo,

ich hätte gern gewusst, ob das hier möglich ist.

Ich hab ein SQL-Skript, das ich ausführen möchte.

und zwar besteht es aus mehreren sql befehlen wie insert, create, drop und select
kann man das ganze gruppieren, zbsp 
string1 = alle insert befehle 
string2 = alle create befehle

und die ausführen mit executeupdate oder execute, je nach befehlsart ??
zbsp gibt er mir 
bei zwei create befehlen hintereinander eine sql-exception
check your syntax at usw usw
aber wenn ich ich die befehle einzeln ausführe, gibt es keine exceptions
könnt ihr mich da kurz aufklären


gruß


essengutallesgut


----------



## abollm (9. Aug 2007)

entegutallesgut hat gesagt.:
			
		

> Hallo,
> 
> ich hätte gern gewusst, ob das hier möglich ist.
> 
> ...



Hm, das kommt darauf an, wie genau du deine gruppierten SQL-Statements ausführen möchtest. Außerdem hängt m.E. die Vorgehensweise stark davon ab, mit welchem RDBMS du arbeitest.

In Oracle gibt es seit 8i die sehr bequeme und relativ einfache Möglichkeit mit NDS dynamisch SQL-Statements in der DB  abzusetzen. Mit dieser Technik ist das von dir Gewünschte recht einfach zu bewerkstelligen.

Eine Frage noch:
Wie genau bist du bei dem oben zitierten "Erzeugen" der SQL-Exception vorgegangen?


----------



## entegutallesgut (9. Aug 2007)

hmmm
ich arbeite mit mySQL 5.0

und die ersten Befehle sehen so aus


String teststring = "DROP TABLE if exists time_points \n"+ 		    	 
"CREATE TABLE time_points(id bigint(20) unsigned NOT NULL auto_increment, \n"+
"time DATETIME NOT NULL UNIQUE,\n"+
"varname VARCHAR(20),PRIMARY KEY (id),\n"+
"INDEX varname USING HASH (varname)) \n"+
"DROP TABLE if exists temp_situations \n"+


"CREATE TABLE temp_situations(id bigint(20) unsigned NOT NULL auto_increment, \n"+
"begin DATETIME NOT NULL,end DATETIME NOT NULL, \n"+
"dim_location VARCHAR(45),dim_activity VARCHAR(45),varname VARCHAR(20), \n"+
"PRIMARY KEY  (id),INDEX begin(begin),INDEX end(end), \n"+
"INDEX varname USING HASH (varname)) \n";		
wenn ich sie einzeln per addbatch in einen statement addiere und ausführem funktioniert das ganze fehlerfrei

aber so, wenn ich statement.execute(test) aus führe, wird folgende meldung ausgegeben

java.sql.SQLException: Syntax error or access violation,  message from server: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TABLE time_points(id bigint(20) unsigned NOT NULL auto_increment, 
time D' at line 2"
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1905)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1109)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1203)
	at com.mysql.jdbc.MysqlIO.sqlQuery(MysqlIO.java:1164)
	at com.mysql.jdbc.Connection.execSQL(Connection.java:2087)
	at com.mysql.jdbc.Connection.execSQL(Connection.java:2037)
	at com.mysql.jdbc.Statement.execute(Statement.java:900)
	at de.fhg.isst.insight.db.tests.TestDB.main(TestDB.java:202)


----------



## tuxedo (9. Aug 2007)

Du musst die einzelnen Statements mit einem ";" voneinander trennen... An jedes Ende eines Statements gehört demnach ein ";".

- Alex

P.S. die "\n" braucht die DB nicht wirklich, kannst du weglassen. Außer du willst die Strings noch "formatiert" auf der Console ausgeben...


----------



## entegutallesgut (9. Aug 2007)

String teststring = "DROP TABLE if exists time_points; \n"+
"CREATE TABLE time_points(id bigint(20) unsigned NOT NULL auto_increment, \n"+
"time DATETIME NOT NULL UNIQUE,\n"+
"varname VARCHAR(20),PRIMARY KEY (id),\n"+
"INDEX varname USING HASH (varname)) ;\n"+
"DROP TABLE if exists temp_situations ;\n"+ 

"CREATE TABLE temp_situations(id bigint(20) unsigned NOT NULL auto_increment, \n"+
"begin DATETIME NOT NULL,end DATETIME NOT NULL, \n"+
"dim_location VARCHAR(45),dim_activity VARCHAR(45),varname VARCHAR(20), \n"+
"PRIMARY KEY (id),INDEX begin(begin),INDEX end(end), \n"+
"INDEX varname USING HASH (varname)); \n";

meinst du etwa wie oben ? das habe ich nämlich auch schon versucht die fehlermeldung ist die selbe und wird am anfang mit ; cor create table ergänzt ..


----------



## abollm (9. Aug 2007)

[Edit]
Ich bin mir jetzt bei MySQL nicht sicher, ob das da auch geht. Aber in Oracle reicht es, wenn du statt des Semikolons am Ende der Zeile unter dem Statement einfach einen Slash (/) einfügst und mit dem Statement absetzt.


----------



## entegutallesgut (9. Aug 2007)

hmm, slash auch versucht, bei # gibt er keine fehlermeldung bezüglich syntax mehr, aber es gibt dann ne fehlermeldung, dass der befehl keine modifikation der sql datenbank durchgeführt hat und nullpointer exception bei
ResultSet rs = stmt.execute(teststring)


----------



## tuxedo (9. Aug 2007)

Benutzt du MySQL? Bin gerade nicht sicher ob man da mit dem jdbc solche kombinierten Statements auf einen rutsch ausführen kann. 

- Alex


----------



## abollm (9. Aug 2007)

alex0801 hat gesagt.:
			
		

> Benutzt du MySQL? Bin gerade nicht sicher ob man da mit dem jdbc solche kombinierten Statements auf einen rutsch ausführen kann.
> 
> - Alex



Hat er doch geschrieben, das er MySQL benutzt. Was soll den bei den angegebenen Statements komplex sein? Da sind doch nur Indizes drauf. OK, noch auto_increment, aber das kann eigentlich nicht der Grund sein.

Müsste ich versuchen nachzuvollziehen. Hab aber gerade keine große Lust MySQL wieder zu installieren.


----------



## tuxedo (10. Aug 2007)

Nein, ich mein nicht die komplexität der einzelnen Statements. Ich sprach von "kombinierten" Statements.

Ich weiß halt nicht wie JDBC reagiert wenn in einem "execute" mehrere Statements stehen...  Weil in der Regel kriegt man ja bei UPDATE oder INSERT Statements ein Ergebnis auf das Query. Eben genau wie bei INSERT. Und wenn da jetzt mehrere Anfragen mit ";" gentrennt in einem "execute" zur DB wandern, weiß ich nicht wie der Treiber die vielen Ergebnisse in einem einzigen "return" bewältigen soll und ob's hier zu Fehlern kommt. Hab bisher immer nur Statement für Statement ausgeführt und nicht mehrere auf einmal.


----------



## abollm (10. Aug 2007)

alex0801 hat gesagt.:
			
		

> Nein, ich mein nicht die komplexität der einzelnen Statements. Ich sprach von "kombinierten" Statements.
> 
> Ich weiß halt nicht wie JDBC reagiert wenn in einem "execute" mehrere Statements stehen...  Weil in der Regel kriegt man ja bei UPDATE oder INSERT Statements ein Ergebnis auf das Query. Eben genau wie bei INSERT. Und wenn da jetzt mehrere Anfragen mit ";" gentrennt in einem "execute" zur DB wandern, weiß ich nicht wie der Treiber die vielen Ergebnisse in einem einzigen "return" bewältigen soll und ob's hier zu Fehlern kommt. Hab bisher immer nur Statement für Statement ausgeführt und nicht mehrere auf einmal.



Stimmt, ich hatte mich verlesen.
Ich denke, du hast recht mit deinen Bemerkungen zu INSERT und UPDATE. Das Einzige was mir dazu als Lösung einfällt, ist so eine Art automatisierte Batch-Verarbeitung. Dabei muss aber die Möglichkeit bestehen, auf einzelne Statements zu reagieren (z.B. Contraint-Verletzung).


----------



## entegutallesgut (15. Aug 2007)

Hmm, also gibts keine Möglichkeit, dass man 
CREATE, INSERT, DROP Befehle hintereinander als Block ausführen kann ??


----------



## tuxedo (15. Aug 2007)

Nö, meines wissens nicht. Du kannst dir aber eine "Wrapper" Methode schreiben die die Statements dann intern einzeln ausführt. Da du ja so erpicht darauf bist alles auf einmal auszuführen, gehe ich davon aus dass dir die Ergebnisse der Statements primär "wurscht" sind. 
Oder hast du dir da noch keine Gedanken drum gemacht?


----------



## entegutallesgut (16. Aug 2007)

hmm, naja, das skript besteht aus zwei drop befehlen, 2 create für zwei temporäre tabellen, dazu noch 4 insert befehle, zum schluss noch eine select-abfrage
alle befehle vor dem select dienen eigentlich der vorbereitung, daher wollte ich das als block ausführen, aber anscheinend gehts nicht,
vielen dank für eure antworten


----------



## tuxedo (16. Aug 2007)

Naja, selbst wenn du's als Block ausführen könntest, hättest du das Problem dass du nicht weißt ob's geklappt hat... Weil du kannst nicht mehrere SQL-Ergebnisse in ein einziges Antwortergebnis verpacken. 

Ergo wäre, selbst wenn du mehr als ein Statement gleichzeitig zur DB übermitteln könntest, dein Programm ein "Schätzeisen".. "Hat's geklappt mit dem eiontragen in die DB? Jepp, ich denke schon.." 

Wenn eins deiner Create's fehlschlagen würde, dann würden auch deine nachfolgenden Insert's und das anschließende Select drunter leiden (weiß nicht wie die miteinander zusammenhängen, ich geh jetzt einfach mal davon aus dass sie aufeinander aufbauen). Und am Ende wüsstest du nicht ob jetzt das erste create, das zweite oder einer deiner 4 insert's den Fehler produziert hat....

Also, bau dir ne Methode die die Statements intern nacheinander absendet und das Ergebnis abwartet.. Von außen musst du die Methode ja nur befüttern und einmal aufrufen. Damit hast du dann auch einen Block, weißt aber bescheid wann wie wo was fehl schlägt.

- Alex

- Alex


----------

