# HSQL Basics



## crimi (4. Okt 2008)

Hey,

ich verzweifel gerade mit HSQL total :\ Irgendwie verstehe ich glaube ich das Grundprinzip nicht. Die mitgelieferte Doku habe ich gelesen, komme aber nicht weiter.

Mein Ziel ist es eine HSQL-DB zu erstellen, die von meiner Java-App gelesen/geschrieben werden kann und alle Inhalte dauerhaft auf der Festplatte speichert.

Dazu will ich eine "In-Process (Standalone) Mode" Datenbank erstellen und die Tabellen mit "CREATE CACHED TABLE" erstellen. 

Die Datenbank will ich über Java erstellen und gehe so vor:

//JDBC Laden
Class.forName("org.hsqldb.jdbcDriver");
//DB aufrufen, falls nicht vorhanden wird sie automatisch erstellt
Connection con = DriverManager.getConnection(jdbc:hsqldb:file:C:/DB, admin, pass);

Hier scheiter ich schon, da die Datenbank irgendwie keine User anlegen kann. Ich kann nur mit User "sa" und ohne Passwort eine DB erstellen.

Was mache ich denn grundsätzlich falsch?!?


----------



## Gelöschtes Mitglied 5909 (4. Okt 2008)

1. 
um user anzulegen:

CREATE USER <username> PASSWORD <password> [ADMIN];

(muss admin sein)
ändern:

ALTER USER <username> SET PASSWORD <password>;

löschen:

DROP USER <username>;

- am anfang gibt es nur SA -> kannst dich nicht mit anderen einloggen

2.

File Mode:

Connection c = DriverManager.getConnection("jdbc:hsqldb:file:testdb", "sa", "");


----------



## Guest (4. Okt 2008)

Schonmal vielen Dank!

Connection con = DriverManager.getConnection(jdbc:hsqldb:file:C:/DB, admin, pass); 
müsste dann ja korrekt sein, mit admin "sa" und pass ""
oder muss ich den Pfad anders angeben?!

Kann ich den "sa" user löschen wenn ich vorher einen anderen admin angelegt habe?

Stimmt es, dass ich alle Tabellen dann als "CREATE CACHED TABLE" anlegen muss, oder würde ein "CREATE TABLE" auch langen, so dass sie dauerhaft in der Datei gespeichert bleibt?


----------



## Gelöschtes Mitglied 5909 (5. Okt 2008)

im file mode werden normale tabellen in der datei persistiert.


> CREATE [MEMORY | CACHED | [GLOBAL] TEMPORARY | TEMP [2] | TEXT[2]] TABLE <name>
> ( <columnDefinition> [, ...] [, <constraintDefinition>...] )
> [ON COMMIT {DELETE | PRESERVE} ROWS];
> 
> Creates a tables in memory (default) or on disk and only cached in memory. If the database is all-in-memory, both MEMORY and CACHED forms of CREATE TABLE return a MEMORY table while the TEXT form is not allowed.



ob man den SA user löschen kann weiß ich nicht, probier es aus.

p.s.: soviel zu du hast die doku gelesen


----------



## crimi (5. Okt 2008)

Danke, aber da in der Doku steht eben nur dass für all-in-memory types die Tabellen immer im Speicher gespeichert werden und eben nicht auf der Platte.

Da steht doch nirgends, dass beim File Mode Tabellen ohne Angabe einfach immer auf der Platte gespeichert werden? Aber wenn das so ist, ist ja gut.

Btw habe ich genau die Stelle plus alle Beschreibungen kurz vorher gelesen, ich finde die total müllig beschrieben.


----------



## Gelöschtes Mitglied 5909 (5. Okt 2008)

> Da steht doch nirgends, dass beim File Mode Tabellen ohne Angabe einfach immer auf der Platte gespeichert werden?



beim *FILE* Mode kann man wohl davon ausgehen dass in einer datei persistiert wird oder etwa nicht ?!?!?!

Und die Außnahmen stehen oben in der Doku drinn
--> ich weiß nicht was du gegen die doku hast


----------



## crimi (6. Okt 2008)

Hey, das geht einfach nicht!

Mein Code:



```
Class.forName("org.hsqldb.jdbcDriver");
		Connection con = DriverManager.getConnection("jdbc:hsqldb:file:C:/DB/test", "sa", "");

		String sqlQuery = null;
		ResultSet rs = null;
		Statement stmt = con.createStatement();	
	
		sqlQuery = "CREATE TABLE spieler (ID INTEGER, vorname CHAR(20), nachname CHAR(20));";
		rs = stmt.executeQuery(sqlQuery);
		

		sqlQuery = "INSERT INTO spieler VALUES (1,'Patrick','S');";
		rs = stmt.executeQuery(sqlQuery);
		sqlQuery = "INSERT INTO spieler VALUES (2,'Daniel','B');";
		rs = stmt.executeQuery(sqlQuery);
		sqlQuery = "INSERT INTO spieler VALUES (3,'Alex','F');";
		rs = stmt.executeQuery(sqlQuery);
```

So, wenn ich jetzt direkt die Daten auslese funktioniert es. Die Tabellen/DB werden also korrekt erstellt. Wenn ich jetzt aber das Programm schliesse, eine andere Klasse öffne, wieder auf die DB zugreifen will und nur lesen will, dann gibt es die Tabellen nicht mehr.

Die Tabellen werden also nur im Cache gespeichert.

In der test.properties steht seltsamerweise folgendes:
[quote
]#HSQL Database Engine 1.8.0.10
#Mon Oct 06 20:53:13 CEST 2008
hsqldb.script_format=0
runtime.gc_interval=0
sql.enforce_strict_size=false
hsqldb.cache_size_scale=8
readonly=false
hsqldb.nio_data_file=true
hsqldb.cache_scale=14
version=1.8.0
hsqldb.default_table_type=memory
hsqldb.cache_file_scale=1
hsqldb.log_size=200
modified=yes
hsqldb.cache_version=1.7.0
hsqldb.original_version=1.8.0
hsqldb.compatible_version=1.8.0
[/quote]

Hast du eine Idee was ich falsch mache?


----------



## Gelöschtes Mitglied 5909 (6. Okt 2008)

du hast kein commit gemacht


----------



## crimi (6. Okt 2008)

1. Ausführung

```
Class.forName("org.hsqldb.jdbcDriver");
		Connection con = DriverManager.getConnection("jdbc:hsqldb:file:C:/DB/test", "sa", "");
		con.setAutoCommit(true);
		
		String sqlQuery = null;
		ResultSet rs = null;
		Statement stmt = con.createStatement();
		
		sqlQuery = "CREATE TABLE spieler (ID INTEGER, vorname CHAR(20), nachname CHAR(20));";
		rs = stmt.executeQuery(sqlQuery);
		
		sqlQuery = "INSERT INTO spieler VALUES (1,'Patrick','Siewerth');";
		rs = stmt.executeQuery(sqlQuery);
```

2. Ausführung

```
Class.forName("org.hsqldb.jdbcDriver");
		Connection con = DriverManager.getConnection("jdbc:hsqldb:file:C:/DB/test", "sa", "");
		
		String sqlQuery = null;
		ResultSet rs = null;
		Statement stmt = con.createStatement();
				
		sqlQuery = "SELECT * FROM  spieler;";
```

Beim 2. kommt der Fehler "table not found", obwohl ich autocommit angeschaltet habe.

Immernoch steht in der test.properties:


> hsqldb.default_table_type=memory



Die ganze Datenbank ist also wohl noch nicht im File Mode, und die Tabellen werden auch nicht dauerhaft gespeichert.

Gibts dafür nicht ein Tutorial wo einfach mal eine Datenbankerstellung mit Tabellen anlegen beispielhaft durchgeführt wird? Sag bitte dass das nicht alles so einfach ist wies aussieht  Wo ist denn mein Fehler?[/code]


----------



## Gelöschtes Mitglied 5909 (6. Okt 2008)

lösche mal alle files die hsql vorher angelegt hat (auch die properties date) und dann machst du das ganze nochmal.
Wenns immernoch nicht geht löscht du wieder alles und machst am schluss mal ein explizites Connection#commit, weil es sein kann dass hsql kein autocommit kann (sollte es können, aber who knows...)


----------



## Gelöschtes Mitglied 5909 (7. Okt 2008)

2 Fehler war schuld dran:

1. du machst execute*Query*, insert, update, delete sind aber keine queries
-> execute() oder executeUpdate()
2. du fährst die DB nicht runter
SHUTDOWN
3. Tipp: verwende PreparedStatements anstatt normaler Statements (hab ich jetzt net weil ich zu faul war deins abzuändern)


```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;


public class HsqlTest {

	public static void main( String[] args ) throws Exception {
	      Class.forName("org.hsqldb.jdbcDriver");
	      Connection con = DriverManager.getConnection("jdbc:hsqldb:file:c:/db/testdb", "sa", "");
	      
	      String sqlQuery = null; 
	   
	      Statement stmt = con.createStatement();   
	      
	      sqlQuery = "CREATE TABLE spieler (ID INTEGER, vorname CHAR(20), nachname CHAR(20));";
	      stmt.executeUpdate(sqlQuery);
	      

	      sqlQuery = "INSERT INTO spieler VALUES (1,'Patrick','S');";
	      stmt.executeUpdate(sqlQuery);
	      sqlQuery = "INSERT INTO spieler VALUES (2,'Daniel','B');";
	      stmt.executeUpdate(sqlQuery);
	      sqlQuery = "INSERT INTO spieler VALUES (3,'Alex','F');";
	      stmt.executeUpdate(sqlQuery); 
	      
	      con.prepareStatement("SHUTDOWN").execute();
	      con.commit();
	}
	
}
```


Führst du nun das ganze 2 mal aus fliegts um die ohren weil die tabelle da ist.


----------



## OneAndZero (22. Okt 2008)

hi,

ich versuche mich auch gerade am selben Problem! Das letzte Stück code geht auch ohne Probleme! Wenn ich das ganze aber aus einer *.jar Datei versuche verweigert er mir die arbeit! Wo könnte da das Problem sein!?
Ich muss das ans laufen bekommen.....


----------



## HoaX (22. Okt 2008)

einfach mal die fehlermeldung lesen ... und uns auch nicht verschweigen


----------



## OneAndZero (22. Okt 2008)

er sagt classNotFoundException zur org.hsqlddb.jdbcDriver
wobei ich aber die hsqldb.jar dem buildpath hinzugefügt habe! 
Die lib befindet sich auch im jar file und in der .classpath datei ist er auch eingetragen!

noch eine andere frage! ich versuche gerade ein für ursprünglich postrgesql oder mssql geschriebene datenbank konfiguration in hsql zu laden, da habe ich z-B. folgendes Problem!

create table TSourceEntities (Id Integer PRIMARY KEY REFERENCES TModelElements, SourceFileId Integer, StartLine Integer, StartChar Integer, EndLine Integer, EndChar Integer, AssemblyFileId Integer);

dort  befindet sich ja ein REFERENCES wie kann ich diesen create Statment lauffähig in hsql bringen! so geht er nicht!

danke schonmal


----------

