![]() |
Datenbank: Firebird • Version: 2.5 • Zugriff über: IbDac
Fehlerhaften ForeinKey finden
Moin allerseits,
in einer DB gibt es eine Tabelle ADRESSEN, die eine Spalte ORT_ID enthält, welche auf die Tabelle ORTE verweist, in der Orte, Postleitzahlen und Vorwahlen eingetragen werden. Die Spalte ORT_ID ist jedoch nicht als Foreign-Key deklariert, die entsprechende Zuweisung erfolgt erst im zugehörigen View. Nun habe ich festgestellt, daß in View_ADRESSEN genau eine Adresse weniger angezeigt wird als in der Tabelle ADRESSEN. Wie das zustandekam, konnte ich mir leicht erklären, denn ich habe gestern den halben Tag damit verbracht, die Tabelle ORTE zu bereinigen, weil dort etliche Orte quasi doppelt vorhanden waren: gleiche Postleitzahl mit anderer Schreibweise des Ortes (z.B. München-Schwabing und München mit derselben PLZ). Ich habe also irgendwo vergessen, einer Adresse die verbliebene ORT_ID zuzuweisen (z.B. München-Schwabing gelöscht, aber die Adresse mit dieser ORT_ID nicht geändert), so daß diese eine Adresse nun eine ORT_ID aufweist, die in der Tabelle ORTE nicht mehr existiert. Wie finde ich diesen Record heraus, ohne händisch alle Tabellen durchgehen zu müssen? Besten Dank für euer Interesse. |
AW: Fehlerhaften ForeinKey finden
Code:
(falls ich dein Problem richtig verstanden habe)
select * from ADRESSEN where ORT_ID not in (select ORT_ID from ORTE)
|
AW: Fehlerhaften ForeinKey finden
Oder so:
Code:
Heißt das ID-Feld in Orte auch ORT_ID?
select *
from adressen a left join orte b on a.ort_id = b.<???> where b.<???> is null |
AW: Fehlerhaften ForeinKey finden
Liste der Anhänge anzeigen (Anzahl: 1)
Für's nächste mal:
|
AW: Fehlerhaften ForeinKey finden
Zitat:
Ich konnte den fehlerhaften Record finden und korrigieren. Nun werden in der Originaltabelle genau so viele Records angezeigt wir im View. Herzlichen Dank dafür :love: Zitat:
Die Version von Olli empfinde ich jedoch als handlicher, weil sie kürzer ist (und nicht, weil sie früher da war). Zitat:
Zitat:
Hab's mir gleich runtergeladen, ausgedruckt und an die Wand gepinnt. |
AW: Fehlerhaften ForeinKey finden
Die "not in" Lösung stoßt aber eher an die Grenzen der DB (Begrenzung der Menge), darum wäre die Lösung von Uwe zu bevorzugen.
Gruß K-H |
AW: Fehlerhaften ForeinKey finden
Zitat:
Also warum sollte ich mir da jetzt tiefere und noch weiter tiefergehende Gedanken machen müssen :?: |
AW: Fehlerhaften ForeinKey finden
Zitat:
Auf die Schnelle hab ich zu Firebird nichts konkretes außer diesem Post gefunden: ![]() Dabei ist nicht klar, ob die Limitierung nur für explizite Aufzählung oder auch für dynamische Selectrückgaben erfolgt. Meine Verständnis ist: (not) in .. für kleineren Abgleich (also adhoc, kleine Komfortabfragen) table join .. für unlimitierten Massenabgleich (also für den Rest) Wenn Du es genau für Deine Version wissen willst, musst Du wohl selbst danach suchen oder es ausprobieren. |
AW: Fehlerhaften ForeinKey finden
Da rächt sich die Ansicht, dass man man aus Zeit-/Kostengründen beim Datenbankdesign auf die Deklaration der Constraints VWzüchten kann, da man diese ja im Programm berücksichtigt.
|
AW: Fehlerhaften ForeinKey finden
Zitat:
;) Zitat:
|
AW: Fehlerhaften ForeinKey finden
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Ist also nicht immer nur die schon fast sprichwörtliche Dummheit oder Unerfahrenheit des Programmierers, die zu Datenbankfehlern führen kann ... |
AW: Fehlerhaften ForeinKey finden
Zitat:
Als weiterer Hinweis: Ist die ORT_ID in der Tabelle Adressen als "NOT NULL" (also als Pflichtfeld) deklariert? Falls nicht, solltest du einen "left outer join" (ähnlich wie in #3) in deine View einbauen, damit dort auch Adressen auftauchen, für die kein Ort angegeben wurde. |
AW: Fehlerhaften ForeinKey finden
Ach, jetzt versteh ich: Klar, die Ort-Id in der Adresstabelle als ForeignKey zu kennzeichnen ist sinnvoll. Hab das soeben nachgeholt:
Code:
alter table ADRESSEN
add constraint FK_ADRESSEN_ORTE foreign key (ORT) references ORTE(ID_ORTE) using desc index IX_ADRESSEN_ORTE Zitat:
|
AW: Fehlerhaften ForeinKey finden
Zitat:
|
AW: Fehlerhaften ForeinKey finden
Da oben steht doch schwarz auf weiß: ALTER TABLE ADRESSEN
Wie kommst du jetzt drauf, ich hätte die Tabelle Orte geändert? Nach dem oben geposteten SQL-Script habe ich nun einen Foreign-Key in der Tabelle Adressen, der auf den den PK der Tabelle ORTE zeigt. Wo siehst du da jetzt ein Problem? |
AW: Fehlerhaften ForeinKey finden
Genau das war doch die Frage: ist es möglich, dass das Foreign-Key-Feld auf Orte in der Adress-Tabelle NULL enthält? Übrigens sind in allen mir bekannten DBMs PK immer NOT NULL und UNIQUE, ohne dass man das explizit angeben müsste. Ohne das könnten sie ihren Zweck ja auch kaum erfüllen.
|
AW: Fehlerhaften ForeinKey finden
Zitat:
|
AW: Fehlerhaften ForeinKey finden
Zitat:
Code:
bei den foreign keys. Lieferant löschen => auch Artikel sind weg, sofern die einen foreign Key auf die Lieferanten-ID haben.
on delete cascade
Jetzt gehts aber irgendwann ums Geld : da sind nämlich noch 2 unbezahlte Rechnungen mit den 10 Artikeln, die ich ja soeben gelöscht habe wegen des Lieferanten. Schreib jetzt mal davon eine Mahnung. Die würde ähnlich aussehen, wie Deine Liste. Wegen der gelöschten Artikel stehen keine Rechnungspositionen auf der Rechnung, eventuell aber ein Endbetrag, weil der mit dem gelöschten Kram prinzipiell nichts zu tun hat. Also, das ganze ist auch ein Rattenschwanz bei dem man verdammt aufpassen muss. Um die verschwundenen Rechnungs-Artikel eventuell noch irgendwie sichtbar zu halten gibts ja noch mehr :
Code:
z.B. oder
on delete set null
Code:
Unbedingt ansehen ! Einfach löschen geht jedenfalls nicht. Bei abhängigen Tabellen komplett auf Foreign Keys zu verzichten, tsts. 8-)
on update cascade
|
AW: Fehlerhaften ForeinKey finden
Ihr geht bei euren Erklärungen aus meiner Sicht etwas zu sehr in die (SQL)Details der Realisierung.
-> Hier geht es doch schlicht um die (derzeit dort wohl fehlende) "Referenzielle Integrität", was für mich die Hauptaufgabe eines DBMS ist, denn Daten in Tabellen speichern&abfragen, das kann man notfalls auch per CSV Dateien. Ein "on delete cascade" wird es in meinen Anwendungen nicht geben. Dort sollen die Exceptions fliegen, wenn wer was zu löschen versucht, was noch anderswo in Benutzung ist. Wenn überhaupt mache ich das per Triggerfunktion, wo dann StepByStep mit voller Absicht alles einzeln gelöscht wird/werden muss. Ein "on update cascade" ist bei mir das einzige, was ich "notfalls" im SingeUserMode für Admins zulasse. Es passiert im Alltag, das mal Artikelnummern "auf die schnelle" von irgendwem angelegt werden, aber derjenige übersieht das es eigentlich eine Struktur gibt, wo sagen wir 1xxxyyyyyy doch was anderes ist wie 2xxxyyyyyy... Anwender sind manchmal kreativ beim einbauen und erfinden von eigenen Zusatzregeln... um sowas dann "in einem Rutsch" zu ändern, so das es sich automatisch auf die gesamte DB auswirkt, egal wo etwas mit diesem Datensatz zu tun hat, genau dafür ist dann ein "on update cascade" brauchbar, aber nicht als Standard. Per Default lasse ich das DBMS eine Execption schmeißen, wenn jemand versucht "Verknüpfungsdaten" einfach so zu ändern. Das mal als einfache "Erklärung" ohne viel DBMS/SQL Speak, denn ich gebe zu, das ich sowas per Datenbankdesigner-Software und nicht per manuellem SQL Script erstelle und konfiguriere... Hauptsache ich weiß, warum ich es tue:) (ps: so Sachen wie unterschiedliche Schreibweisen funktionieren bei mir mit zusätzlichen Alias-Tabellen in diesem Fall z.B. über PLZ+Vorwahl als Zusatzschlüssel) |
AW: Fehlerhaften ForeinKey finden
Zitat:
Wie oben bereits berichtet, entstanden durch das Einlesen von "unordentlichen" Listen Orte mit unterschiedlichen Schreibweisen, aber gleichen Postleitzahlen. Das ließe sich nur vermeiden, wenn man die Listen vor dem Einlesen manuell am Editor durchforstet, und das wäre ja wohl der Gipfel der Zeitverschwendung ... und der zermürbenden Arbeit ... Diese Listen müssen von mir nur einmal eingelesen werden, der Anwender bearbeitet die Datenbank-Einträge dann per Hand ... so viele neue Firmen werden in dieser Branche nicht ständig gegründet und beim Anwender angemeldet, daß er das nicht manuell bewältigen könnte. So kann er dann prüfen, ob der Eintrag korrekt ist, die Firmendaten stimmen usw. Die Listen, die ich einmalig einlese und oberflächlich verifiziere, sind dagegen in einem Zeitraum von zig Jahren entstanden. Zitat:
Daß das Thema hier trotz bereits erfolgter Problemlösung ständig weitere Kommentare erhält, die meinem Empfinden nach einer teilweise fragwürdigen Intention geschuldet sind, hat mich ein wenig verwundert ... nur ein wenig deshalb, weil das hier im Grunde täglich zu beobachten ist. |
AW: Fehlerhaften ForeinKey finden
Was hier versucht wurde, nennt sich 'Recording Linking' oder einfacher 'Deduplizierung'. Eigentlich ist der Prozess viel komplexer, Perlsau hat die Vorarbeit implizit durch die Orte-Tabelle schon geleistet.
Hier wäre folgende Vorgehensweise sinnvoll gewesen: Im ersten Schritt werden Duplikate erkannt und verknüpft. z.B. über eine Link-Tabelle. Im zweiten Schritt kann man die Duplikat-IDs in der referenzierenden Tabelle durch die Original-ID ersetzen. Im letzten Schritt können dann die Duplikate sicher entsorgt werden. Natürlich ersetzt das nicht die notwendige Sicherstellung der referenziellen Integrität durch entsprechende Constraints. |
AW: Fehlerhaften ForeinKey finden
Zitat:
Nun denn, dann eben One-Man-Show und Perlsau ist kurz glücklich bis zum nächsten Crash. Zitat:
|
AW: Fehlerhaften ForeinKey finden
Das Problem ist imho dadurch gelöst, das:
1. Ein Foreign Key Constraint angelegt wurde bzw. beim nächsten Mal angelegt wird. 2. Auf 'Record Linkage' und 'Deduplication' verwiesen wurde, da es sich um ein Standardproblem handelt. Desweiteren geht es hier nicht um das Anti-Pattern 'Sprechende eindeutige Werte sind gleichzeitig PK'. Nebenbei: Man kann in seiner Artikelnummer soviel kodieren, wie man möchte, nur darf man diese NIE NIE NIEMALS als PK verwenden. Als PK eignet sich !nur! eine anonyme ID, die keine Sau interessiert, die man nie sieht, über dessen Aussehen sich niemand aufregt und die einfach nur eine ID ist. Mehr nicht. Ein AutoInc ist dafür geeignet, oder eine GUID oder was weiß ich. Aber *KEINE* Artikelnummer. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz