# Problem mit Create-Statement



## alex1511 (28. Dez 2012)

Hallo zusammen,

ich möchte gerne aus einem Java-Programm heraus einige Tabellen erstellen, die auf einer MySQL-Datenbank bei meinem Provider liegen. Das funktioniert auch tadellos, bis eine einzige Tabelle. 

Der SQL-Code sieht folgendermaßen aus

```
CREATE  TABLE IF NOT EXISTS `db_270387_1`.`Exhibit` (
  `IDExhibit` INT NOT NULL AUTO_INCREMENT ,
  `ExhibitName` TINYTEXT NULL ,
  `Amount` INT NULL ,
  `Description` VARCHAR(500) NULL ,
  `rfidTag` VARCHAR(24) NULL ,
  `inExhibition` TINYINT(1) NULL ,
  `IDSection` INT NULL ,
  `IDCatalog` INT NULL ,
  `NameMuseumHolder` VARCHAR(100) NULL ,
  `NameMuseumPropertier` VARCHAR(100) NULL ,
  PRIMARY KEY (`IDExhibit`) ,
  UNIQUE INDEX `EXP ID_UNIQUE` (`IDExhibit` ASC) ,
  INDEX `SektionIDFKEx_idx` (`IDSection` ASC) ,
  INDEX `IDCatalogFKEx_idx` (`IDCatalog` ASC) ,
  INDEX `NaMuseumHoFKEx_idx` (`NameMuseumHolder` ASC) ,
  INDEX `NaMuseumPrFKEx_idx` (`NameMuseumPropertier` ASC) ,
  CONSTRAINT `IDSectionFKEx`
    FOREIGN KEY (`IDSection` )
    REFERENCES `db_270387_1`.`Section` (`IDSection` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `IDCatalogFKEx`
    FOREIGN KEY (`IDCatalog` )
    REFERENCES `db_270387_1`.`Catalog` (`IDCatalog` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `NaMuseumHoFKEx`
    FOREIGN KEY (`NameMuseumHolder` )
    REFERENCES `db_270387_1`.`Museums` (`MuseumName` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `NaMuseumPrFKEx`
    FOREIGN KEY (`NameMuseumPropertier` )
    REFERENCES `db_270387_1`.`Museums` (`MuseumName` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;
```

Führe ich diesen Code in der MySQL-Workbench oder dem PHP-MyAdmin aus funktioniert er und die Tabelle wird problemlos erstellt.

Binde ich ihn jedoch in mein Java-Programm ein bekomme ich folgende Fehlermeldung:
Can't create table 'db_270387_1.Exhibit' (errno: 150)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
	at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1379)
	at dataStorageAccess.DatabaseInstallation.initializeOnlineTables(DatabaseInstallation.java:369)
	at dataStorageAccess.DatabaseInstallation.installOnlineDatabase(DatabaseInstallation.java:34)
	at dataStorageAccess.DataStorageAccess.installOnlineDatabase(DataStorageAccess.java:56)
	at userInterface.OnlineTest.onlineMain(OnlineTest.java:21)
	at userInterface.Main.main(Main.java:29)

der entsprechende Java-Code sieht so aus:

```
DatabaseManager.getTestServerConnection().prepareStatement("CREATE  TABLE IF NOT EXISTS `db_270387_1`.`Exhibit` (`IDExhibit` INT NOT NULL AUTO_INCREMENT ," +
				"`ExhibitName` TINYTEXT NULL ,`Amount` INT NULL ,`Description` VARCHAR(500) NULL ,`rfidTag` VARCHAR(24) NULL ,`inExhibition` TINYINT(1) NULL ," +
				"`IDSection` INT NULL ,`IDCatalog` INT NULL ,`NameMuseumHolder` VARCHAR(100) NULL ,`NameMuseumPropertier` VARCHAR(100) NULL ," +
				"PRIMARY KEY (`IDExhibit`) ,UNIQUE INDEX `EXP ID_UNIQUE` (`IDExhibit` ASC) ,INDEX `SektionIDFKEx_idx` (`IDSection` ASC) ,INDEX `IDCatalogFKEx_idx` (`IDCatalog` ASC) ,INDEX `NaMuseumHoFKEx_idx` (`NameMuseumHolder` ASC) ,INDEX `NaMuseumPrFKEx_idx` (`NameMuseumPropertier` ASC) ," +
				"CONSTRAINT `IDSectionFKEx` FOREIGN KEY (`IDSection` ) REFERENCES `db_270387_1`.`Section` (`IDSection` ) ON DELETE CASCADE ON UPDATE CASCADE, " +
				"CONSTRAINT `IDCatalogFKEx` FOREIGN KEY (`IDCatalog` ) REFERENCES `db_270387_1`.`Catalog` (`IDCatalog` ) ON DELETE CASCADE ON UPDATE CASCADE, " +
				"CONSTRAINT `NaMuseumHoFKEx` FOREIGN KEY (`NameMuseumHolder` ) REFERENCES `db_270387_1`.`Museums` (`MuseumName` ) ON DELETE CASCADE ON UPDATE CASCADE, " +
				"CONSTRAINT `NaMuseumPrFKEx` FOREIGN KEY (`NameMuseumPropertier` ) REFERENCES `db_270387_1`.`Museums` (`MuseumName` ) ON DELETE CASCADE ON UPDATE CASCADE) " +
				"ENGINE = InnoDB;").execute();
```

hat von euch jemand eine Idee, wo da der Fehler liegt?

Gruß, Alex


----------



## Marcinek (28. Dez 2012)

[STRIKE]Prepare Statements können keine DDL ausführen.[/STRIKE]

[STRIKE]Doch können sie, aber dann muss man executeUpdat() nutzen und nicht execute();[/STRIKE]

Ok müsste mit beiden gehen. Versuch es mal mit einer weniger komplizierten DDL.


----------



## alex1511 (28. Dez 2012)

Grundsätzlich funktioniert der Zugriff auf die Datenbank. Abgesehen von dieser Tabelle gehören zu der Datenbank noch 12 weitere, ähnlich umfangreiche, Tabellen. Diese werden alle problemlos erstellt. Da ich das Statement ohne Probleme mittels Workbench oder PHP-MyAdmin ausführen kann, liegt der Fehler, meiner Ansicht nach, nicht in der SQL-Syntax. 
Aus irgendeinem Grund führt dieses Statement, in Verbindung mit dem restlichen Java-Code, jedoch zu oben genannten Fehler.


----------



## OlliL (28. Dez 2012)

errno 150 ist foreign key fehler wenn mich nicht alles täuscht. Zeige doch mal die Key-Definitionen der referenzierten Tabellen. Ggfl. passt da was nicht zusammen. Ggfl. unsigned die Spalte in Tabelle A aber nicht in Tabelle B. Ältere MySQL Versionen (4.x?) brauchen auch Indizes unter ihren Keys - neue legen die autom. an....


----------



## alex1511 (28. Dez 2012)

okay, also im folgenden dann die referenzierten Tabellen:


```
CREATE  TABLE IF NOT EXISTS `db_270387_1`.`Section` (
  `IDSection` INT NOT NULL ,
  `IDUpperSection` INT NULL ,
  `SectionName` VARCHAR(45) NULL ,
  `Type` VARCHAR(45) NULL ,
  `IDMuseum` INT NULL ,
  PRIMARY KEY (`IDSection`) ,
  UNIQUE INDEX `IDSection_UNIQUE` (`IDSection` ASC) ,
  INDEX `IDUpperSectionFKSe_idx` (`IDUpperSection` ASC) ,
  INDEX `IDMuseumFKSe_idx` (`IDMuseum` ASC) ,
  CONSTRAINT `IDUpperSectionFKSe`
    FOREIGN KEY (`IDUpperSection` )
    REFERENCES `db_270387_1`.`Section` (`IDSection` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `IDMuseumFKSe`
    FOREIGN KEY (`IDMuseum` )
    REFERENCES `db_270387_1`.`Museums` (`IDMuseum` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;
```


```
CREATE  TABLE IF NOT EXISTS `db_270387_1`.`Catalog` (
  `IDCatalog` INT NOT NULL AUTO_INCREMENT ,
  `IDUpperCatalog` INT NULL ,
  `CatalogName` VARCHAR(45) NULL ,
  `IDMuseum` INT NULL ,
  PRIMARY KEY (`IDCatalog`) ,
  UNIQUE INDEX `IDCatalogFKCa_UNIQUE` (`IDCatalog` ASC) ,
  INDEX `IDMuseumFKCa_idx` (`IDMuseum` ASC) ,
  INDEX `IDUpperCatalogFKCa_idx` (`IDCatalog` ASC) ,
  CONSTRAINT `IDMuseumFKCa`
    FOREIGN KEY (`IDMuseum` )
    REFERENCES `db_270387_1`.`Museums` (`IDMuseum` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `IDUpperCatalogFKCa`
    FOREIGN KEY (`IDCatalog` )
    REFERENCES `db_270387_1`.`Catalog` (`IDCatalog` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;
```


```
CREATE  TABLE IF NOT EXISTS `db_270387_1`.`Museums` (
  `IDMuseum` INT NOT NULL AUTO_INCREMENT ,
  `MuseumName` VARCHAR(100) NOT NULL ,
  `Description` TEXT NULL ,
  `eMail` VARCHAR(45) NULL ,
  `Tel` VARCHAR(45) NULL ,
  `Tel2` VARCHAR(45) NULL ,
  `IDAddress` INT NULL ,
  PRIMARY KEY (`IDMuseum`) ,
  INDEX `IDAddressFKMu_idx` (`IDAddress` ASC) ,
  UNIQUE INDEX `IDMuseum_UNIQUE` (`IDMuseum` ASC) ,
  UNIQUE INDEX `MuseumName_UNIQUE` (`MuseumName` ASC) ,
  CONSTRAINT `IDAddressFKMu`
    FOREIGN KEY (`IDAddress` )
    REFERENCES `db_270387_1`.`Address` (`IDAddress` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;
```

Um den Zusammenhang grad ein wenig zu erklären. Das ganze wird eine Verwaltungssoftware für ein Museum. Das Museum hat hierbei die Möglichkeit seine Exponate (Exhibits) in verschiedene Kataloge und Sectionen zu ordnen.

Die 3 oben genannten Tabellen werden problemlos installiert


----------



## OlliL (29. Dez 2012)

Mein heisser Tipp:

PHPMyadmin oder die MySQL-Workbench legen die Tabellen mit einem anderen Charset an als unter Java.
legt man z.B. deine 3 Tabellen mit latin1 Charset an, und die 4. Tabelle aus deinem 1. Posting mit UTF8, kommt es auch zu einem errno 150.

finde mal raus mit welchem Charset die 3 Tabellen angelegt wurden (z.B. mit "show create table Museums;"). Und dann packst du diesen gleichen Zeichensatz an das CREATE-Statement aus Posting 1 ran. Also z.B. "..... ) ENGINE=InnoDB DEFAULT CHARSET=latin1;"

In MySQL :: MySQL 5.5 Reference Manual :: 14.3.5.4 FOREIGN KEY Constraints stehts auch nochmal schön:



> For nonbinary (character) string columns, the character set and collation must be the same.


----------



## alex1511 (30. Dez 2012)

Danke für den Tipp, hab leider gerade erst wieder Zeit gehabt es zu testen. Leider bekomme ich den selben Fehler. Sowohl mit utf-8 als Charset, als auch mit latin1.


----------



## OlliL (30. Dez 2012)

In welchem Charset sind denn die anderen Tabellen angelegt worden?


----------



## alex1511 (30. Dez 2012)

alle mit utf8


----------



## alex1511 (30. Dez 2012)

Ich hab den Fehler grad gefunden. Es lag daran, dass ich mit 

"CONSTRAINT `IDCatalogFKEx` FOREIGN KEY (`IDCatalog` ) REFERENCES `Catalog` (`IDCatalog` ) ON DELETE CASCADE ON UPDATE CASCADE, "

einen Fremdschlüssel auf eine nicht existierende Tabelle erstellen wollte. Offenbar hatte ich die schlichtweg vergessen diese in den Java-Code zu übertragen. Blöder Fehler.

Ich danke euch für eure Hilfe!

Liebe Grüße, Alex


----------

