FK Constraint auf 2 Tabellen
FK Constraint auf 2 Tabellen
am 21.08.2006 10:03:36 von FerKuLon
Hallo,
ich habe (wie nicht anders zu erwarten) ein kleines Problem und
brauchte mal einen Stubser in die
richtige Richtung - komme nämlich gerade nicht weiter.
Ich habe eine Eingabemaske, in der werden Werte aus 2 Tabellen
(b1_ref_1,b1_ref_2) in einem Select-
feld zur Auswahl angeboten. Der Wert wird dann in der Tabelle b1_reffer
gespeichert. Um ein Löschen
von referenzierten Werten zu verhindern habe ich zwei FK Constraints
erzeugt. Diese zeigen auf die
jeweiligen Spalten der Tabellen auf die referenziert wird.
Das klappt auch solange in den referenzierten Tabellen die gleiche
Anzahl von Datensätzen vorhanden
ist. Sind in b1_ref_1 und b1_ref_2 unterschiedlich viele Datensätze,
dann bekomme ich den MySQL Fehler
1452 (Fehler: 1452 SQLSTATE: 23000 (ER_NO_REFERENCED_ROW_2) - Meldung:
Kann Kind-Zeile nicht hinzufügen
oder aktualisieren: eine Fremdschlüsselbedingung schlägt fehl (%s)).
Ich hab nun schon einiges probiert, komme aber nicht weiter. Vielleicht
hatte ja hier schon jemand ein
ähnliches Problem oder sieht etwas was ich übersehen habe. Ich habe
die Tabellenstrukturen mal mit an-
gehängt. Das sind meine Testtabellen.
Jan
CREATE TABLE `b1_reffer` (
`id` int(10) unsigned NOT NULL auto_increment,
`generator_ref_table` varchar(255) collate latin1_german1_ci NOT
NULL,
`LastChanged` timestamp NOT NULL default CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP,
`WhoChanged` int(11) default '0',
`ref_1` int(11) default NULL,
`ref_2` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `ref_1` (`ref_1`),
KEY `ref_2` (`ref_2`)
) ENGINE=3DInnoDB DEFAULT CHARSET=3Dlatin1 COLLATE=3Dlatin1_german1_ci
AUTO_INCREMENT=3D1 ;
--
-- Constraints der Tabelle `b1_reffer`
--
ALTER TABLE `b1_reffer`
ADD CONSTRAINT `b1_reffer_ibfk_3` FOREIGN KEY (`ref_2`) REFERENCES
`b1_ref_2` (`id`) ON UPDATE CASCADE,
ADD CONSTRAINT `b1_reffer_ibfk_1` FOREIGN KEY (`ref_1`) REFERENCES
`b1_ref_3` (`id`) ON UPDATE CASCADE,
ADD CONSTRAINT `b1_reffer_ibfk_2` FOREIGN KEY (`ref_2`) REFERENCES
`b1_ref_1` (`id`) ON UPDATE CASCADE;
CREATE TABLE `b1_ref_1` (
`id` int(11) NOT NULL auto_increment,
`key_idSubproject` int(11) default '0',
`key_idInformationObject` int(11) default '0',
`key_idPhysicalObject` int(11) default '0',
`key_nameSubproject` varchar(20) collate latin1_german1_ci NOT NULL,
`key_counter` varchar(3) collate latin1_german1_ci NOT NULL,
`key_date` date NOT NULL default '0000-00-00',
`generator_ref_table` varchar(255) collate latin1_german1_ci NOT
NULL,
`LastChanged` timestamp NOT NULL default CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP,
`WhoChanged` int(11) default '0',
`test` varchar(255) collate latin1_german1_ci default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `sfb639key`
(`key_idSubproject`,`key_idInformationObject`,`key_idPhysica lObject`,`key_n=
ameSubproject`,`key_counter`,`key_date`),
KEY `key_idInformationObject` (`key_idInformationObject`),
KEY `key_idPhysicalObject` (`key_idPhysicalObject`)
) ENGINE=3DInnoDB DEFAULT CHARSET=3Dlatin1 COLLATE=3Dlatin1_german1_ci
AUTO_INCREMENT=3D4 ;
CREATE TABLE `b1_ref_2` (
`id` int(11) NOT NULL auto_increment,
`key_idSubproject` int(11) default '0',
`key_idInformationObject` int(11) default '0',
`key_idPhysicalObject` int(11) default '0',
`key_nameSubproject` varchar(20) collate latin1_german1_ci NOT NULL,
`key_counter` varchar(3) collate latin1_german1_ci NOT NULL,
`key_date` date NOT NULL default '0000-00-00',
`generator_ref_table` varchar(255) collate latin1_german1_ci NOT
NULL,
`LastChanged` timestamp NOT NULL default CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP,
`WhoChanged` int(11) default '0',
`test` varchar(255) collate latin1_german1_ci default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `sfb639key`
(`key_idSubproject`,`key_idInformationObject`,`key_idPhysica lObject`,`key_n=
ameSubproject`,`key_counter`,`key_date`),
KEY `key_idInformationObject` (`key_idInformationObject`),
KEY `key_idPhysicalObject` (`key_idPhysicalObject`)
) ENGINE=3DInnoDB DEFAULT CHARSET=3Dlatin1 COLLATE=3Dlatin1_german1_ci
AUTO_INCREMENT=3D1 ;
CREATE TABLE `b1_ref_3` (
`id` int(11) NOT NULL auto_increment,
`key_idSubproject` int(11) default '0',
`key_idInformationObject` int(11) default '0',
`key_idPhysicalObject` int(11) default '0',
`key_nameSubproject` varchar(20) collate latin1_german1_ci NOT NULL,
`key_counter` varchar(3) collate latin1_german1_ci NOT NULL,
`key_date` date NOT NULL default '0000-00-00',
`generator_ref_table` varchar(255) collate latin1_german1_ci NOT
NULL,
`LastChanged` timestamp NOT NULL default CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP,
`WhoChanged` int(11) default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `sfb639key`
(`key_idSubproject`,`key_idInformationObject`,`key_idPhysica lObject`,`key_n=
ameSubproject`,`key_counter`,`key_date`),
KEY `key_idInformationObject` (`key_idInformationObject`),
KEY `key_idPhysicalObject` (`key_idPhysicalObject`)
) ENGINE=3DInnoDB DEFAULT CHARSET=3Dlatin1 COLLATE=3Dlatin1_german1_ci
AUTO_INCREMENT=3D4 ;
Re: FK Constraint auf 2 Tabellen
am 21.08.2006 10:54:19 von Alex Hepp
Grüß Dich!
FerKuLon schrieb:
^^^^^^^^^ RealName?
> Ich habe eine Eingabemaske, in der werden Werte aus 2 Tabellen
> (b1_ref_1,b1_ref_2) in einem Select- feld zur Auswahl angeboten.
Wirklich in einem Feld? Wie extrahierst Du dann die unterschiedlichen
Werte wieder?
> Der Wert wird dann in der Tabelle b1_reffer gespeichert. Um ein
> Löschen von referenzierten Werten zu verhindern habe ich zwei FK
> Constraints erzeugt. Diese zeigen auf die jeweiligen Spalten der
> Tabellen auf die referenziert wird.
>
> Das klappt auch solange in den referenzierten Tabellen die gleiche
> Anzahl von Datensätzen vorhanden ist. Sind in b1_ref_1 und b1_ref_2
> unterschiedlich viele Datensätze, dann bekomme ich den MySQL Fehler
> [...]
Das dürfte nicht sein, das Einzige, was sein kann, ist, dass Du
versuchst, einen referenzwert einzutragen, der so nicht vorhanden ist...
Schon mal geschaut, ob Du vielleicht die Werte vertauscht hast, und den
für ref1 bei ref2 einzutragen versuchst, o.ä. ? Die Werte, die Du in ein
mit einem FK belegtes Feld eintragen möchtest, müssen definitiv bereits
in der referenzierten Spalte vorhanden sein, sonst läuft das nicht...
> CREATE TABLE `b1_reffer` [...]
Du kannst die FK-Constraints dieser Tabelle erst anlegen, wenn auch die
anderen Tabellen existieren... Nur so als Hinweis.
HTH Alex
Re: FK Constraint auf 2 Tabellen
am 21.08.2006 11:56:47 von FerKuLon
Hi Alex,
ich erkläre kurz den Hintergrund, um es deutlicher zu machen. Ursache
für dieses
Problem (in meinem speziellen Fall) ist, das es in der Anwendung, in
der es mal
eingebaut werden soll, 2 Tabellen gibt, in denen Materialdaten abgelegt
werden.
Per Definition darf ich die Daten leider nicht in eine werfen, sonder
es müssen
diese beiden Tabellen bleiben.
Ich lese also die Materialdaten der Tabellen aus und gebe sie
(wirklich) in EINEM
Select Feld aus. Der Value des Option Feldes sieht dann zB. so aus:
12#b1_ref_1.
Dabei steht vor der Raute die id des Datensatzes in der Tabelle
(Tabellenname steht
nach der Raute). Vor dem Eintragen des Wertes wird dieser Wert einfach
wieder
auseinandergenommen. In die Tabelle trage ich dann die id des
Datensatzes und
die Tabelle (bzw. den Namen der Tabelle) ein. Somit kann ich den
Datensatz
genau zuordnen.
Ich habe die beiden Tabellen mit den Werten angelegt und dann darauf
referenziert,
die Werte sind also in den Tabellen (auf die ich referenziere) schon da
- sonst
würden sie ja in meinem Select Feld nicht zu sehen sein =3D).
Das anlegen der Constraints klappt ja auch. Ich kann sogar Werte in
meiner Tabelle
referenzieren. Wenn ich diese dan in der Tabelle mit den Werten
löschen will be-
komme ich auch die Meldung das dies nicht geht, da eine
FK-Einschränkung gilt.
Du siehst, das ganze funktioniert schon. Nur wenn ich in den Tabellen
mit den
Materialdaten unterschiedlich viele Datensätze habe, dann kommt der
beschriebene
MySQL Fehler.
Ich habe ja diese 2 Constraints, die jeweils auf die id der zu
referenzierenden
Tabellen mit den Materialdaten zeigen:
ALTER TABLE `b1_reffer`
ADD CONSTRAINT `b1_reffer_ibfk_3` FOREIGN KEY (`ref_2`) REFERENCES
`b1_ref_2` (`id`) ON UPDATE CASCADE,
ADD CONSTRAINT `b1_reffer_ibfk_2` FOREIGN KEY (`ref_2`) REFERENCES
`b1_ref_1` (`id`) ON UPDATE CASCADE;
Könnte es sein, dass ich diese vielleicht nicht einzeln definieren
darf, sondern
zu einem Statement zusammenfügen muss - nur son wirrer Gedanke =3D).
Leider ist
diese Applikation hier meine Erste Anwendung, in der ich FK-Constraints
verwende,
habe also noch keine größeren Erfahrungen auf diesem Gebiet sammeln
können.
Ach ja, ich sollte vielleicht noch sagen, das es eine MySQL 5.0 ist mit
der ich
hier arbeite.
VIelen Dank schon mal für Deine Mühe ... stehe gerade bissi auf dem
Schauch.
Jan
Alex Hepp wrote:
> Grüß Dich!
>
> FerKuLon schrieb:
> ^^^^^^^^^ RealName?
>
> > Ich habe eine Eingabemaske, in der werden Werte aus 2 Tabellen
> > (b1_ref_1,b1_ref_2) in einem Select- feld zur Auswahl angeboten.
>
> Wirklich in einem Feld? Wie extrahierst Du dann die unterschiedlichen
> Werte wieder?
>
> > Der Wert wird dann in der Tabelle b1_reffer gespeichert. Um ein
> > Löschen von referenzierten Werten zu verhindern habe ich zwei FK
> > Constraints erzeugt. Diese zeigen auf die jeweiligen Spalten der
> > Tabellen auf die referenziert wird.
> >
> > Das klappt auch solange in den referenzierten Tabellen die gleiche
> > Anzahl von Datensätzen vorhanden ist. Sind in b1_ref_1 und b1_ref_2
> > unterschiedlich viele Datensätze, dann bekomme ich den MySQL Fehler
> > [...]
>
> Das dürfte nicht sein, das Einzige, was sein kann, ist, dass Du
> versuchst, einen referenzwert einzutragen, der so nicht vorhanden ist...
> Schon mal geschaut, ob Du vielleicht die Werte vertauscht hast, und den
> für ref1 bei ref2 einzutragen versuchst, o.ä. ? Die Werte, die Du in =
ein
> mit einem FK belegtes Feld eintragen möchtest, müssen definitiv berei=
ts
> in der referenzierten Spalte vorhanden sein, sonst läuft das nicht...
>
> > CREATE TABLE `b1_reffer` [...]
>
>
> Du kannst die FK-Constraints dieser Tabelle erst anlegen, wenn auch die
> anderen Tabellen existieren... Nur so als Hinweis.
>
> HTH Alex
Alex Hepp wrote:
> Grüß Dich!
>
> FerKuLon schrieb:
> ^^^^^^^^^ RealName?
>
> > Ich habe eine Eingabemaske, in der werden Werte aus 2 Tabellen
> > (b1_ref_1,b1_ref_2) in einem Select- feld zur Auswahl angeboten.
>
> Wirklich in einem Feld? Wie extrahierst Du dann die unterschiedlichen
> Werte wieder?
>
> > Der Wert wird dann in der Tabelle b1_reffer gespeichert. Um ein
> > Löschen von referenzierten Werten zu verhindern habe ich zwei FK
> > Constraints erzeugt. Diese zeigen auf die jeweiligen Spalten der
> > Tabellen auf die referenziert wird.
> >
> > Das klappt auch solange in den referenzierten Tabellen die gleiche
> > Anzahl von Datensätzen vorhanden ist. Sind in b1_ref_1 und b1_ref_2
> > unterschiedlich viele Datensätze, dann bekomme ich den MySQL Fehler
> > [...]
>
> Das dürfte nicht sein, das Einzige, was sein kann, ist, dass Du
> versuchst, einen referenzwert einzutragen, der so nicht vorhanden ist...
> Schon mal geschaut, ob Du vielleicht die Werte vertauscht hast, und den
> für ref1 bei ref2 einzutragen versuchst, o.ä. ? Die Werte, die Du in =
ein
> mit einem FK belegtes Feld eintragen möchtest, müssen definitiv berei=
ts
> in der referenzierten Spalte vorhanden sein, sonst läuft das nicht...
>
> > CREATE TABLE `b1_reffer` [...]
>
>
> Du kannst die FK-Constraints dieser Tabelle erst anlegen, wenn auch die
> anderen Tabellen existieren... Nur so als Hinweis.
>=20
> HTH Alex
Re: FK Constraint auf 2 Tabellen
am 21.08.2006 17:33:47 von Alex Hepp
Hallo Jan (bitte ändere auch noch Deinen Eintrag im NewsReader auf
Deinen Real Namen (auch mit Nachnamen))... das verschafft mehr Seriösität ;)
FerKuLon schrieb:
> Hi Alex,
>
> [...Hintergrundgeschichte... ;)] Ich lese also die Materialdaten der
> Tabellen aus und gebe sie (wirklich) in EINEM Select Feld aus. Der
> Value des Option Feldes sieht dann zB. so aus: 12#b1_ref_1.
Naja, allerdings steht in einem SELECT auch nur EIN Referenzwert, und
nicht in einem SELECT die Referenzen für beide...
Die Frage ist jetzt, was passiert, wenn das Formular abgeschickt wird,
hast Du dann Werte für die beiden Referenzen, sprich eine ID für
b1_ref_1 und eine für b1_ref_2 ?
> [...] Du siehst, das ganze funktioniert schon. Nur wenn ich in den
> Tabellen mit den Materialdaten unterschiedlich viele Datensätze habe,
> dann kommt der beschriebene MySQL Fehler.
Einem FK ist es meines Wissens vollkommen egal, wieviele Datensätze die
referenzierte Tabelle aufweist... Was ich mir vorstellen könnte, ist
folgendes: Du trägst vielleicht aus Versehen entweder vertauscht ein
(sprich die ID für b1_ref_1 in die Spalte, die auf b1_ref_2 verweist,
oder andersherum). das macht eben dann keine Probleme, wenn beide
Tabellen gleich viele Einträge haben, da Du ja autoincrement verwendest,
und dann eben auch die ID in der anderen Tabelle vorhanden ist. Schau
noch mal genau hin ;)
> ALTER TABLE `b1_reffer` ADD CONSTRAINT `b1_reffer_ibfk_3` FOREIGN KEY
> (`ref_2`) REFERENCES `b1_ref_2` (`id`) ON UPDATE CASCADE, ADD
> CONSTRAINT `b1_reffer_ibfk_2` FOREIGN KEY (`ref_2`) REFERENCES
> `b1_ref_1` (`id`) ON UPDATE CASCADE;
>
> Könnte es sein, dass ich diese vielleicht nicht einzeln definieren
> darf, sondern zu einem Statement zusammenfügen muss - nur son wirrer
> Gedanke =).
Ne, nich das ich wüsste ;) geht ja auch irgendwie garnich, bedenke, dass
ein FK eine Referenz einer Spalte auf eine andere ist, wüsste nicht, wie
man das zusammenführen soll?
Noch ein Tipp: Besser keine ToFus machen (sprich einfach Deine Antwort
über den komplett eingebundenen zitierten Text schreiben).
schau mal hier:
http://www.afaik.de/usenet/faq/zitieren/
Viel Glück...
Alex