Aktualisierung Werte in einer "aus einer anderen" Tabelle

Hallo,
leider fiel mir kein anderer Betreff ein. :rolleyes:

Im Zuge eines Updates möchte ich auch Optimierungen an der Datenbank vornehmen, wegen eines NOTWENDIGEN Änderungsnachweises, den ich aktuell per Trigger realisiert habe, müssen die vorhandenen Daten nach der Migration auch wieder korrekt zugeordnet werden können. In meinem aktuellen Szenario übernehme ich den PrimaryKey nicht in die migrierte Datenbank und muß daher “abhängige” Datensätze in anderen Tabellen entsprechend aktualisieren, dies klappt auch soweit.

Mein Änderungsnachweis sieht so aus:

CREATE TABLE public.tupda
(
  pk_upda integer NOT NULL DEFAULT nextval('public.tupda_seq'::regclass),
  aenderung_nutzer character varying(60) NOT NULL DEFAULT ''::character varying,
  aenderung_datum date NOT NULL DEFAULT now(),
  aenderung_zeit time without time zone NOT NULL DEFAULT now(),
  aenderung_tabelle character varying(5) NOT NULL DEFAULT ''::character varying,
  aenderung_feld character varying(2500) NOT NULL DEFAULT ''::character varying,
  aenderung_wert_alt character varying(2500) DEFAULT ''::character varying,
  aenderung_wert_neu character varying(2500) DEFAULT ''::character varying,
  primary_key_wert integer NOT NULL DEFAULT 0,
  CONSTRAINT pk_upda PRIMARY KEY (pk_upda)
)

Jede Änderung an den Datensätzen wird hier mittels Triggerfunktion gespeichert. Bei meinem Problem geht es um die Spalte “primary_key_wert”, welcher den PrimaryKey in der betroffenen Tabelle enthält.

Bei der Migration erweitere ich die Tabelle zu welcher ich den Änderungsnachweis vorhalten muß um ein Feld, in welches ich den “alten” PrimaryKey übernehme, welcher mit dem Inhalt der Spalte “primary_key_wert” übereinstimmt. Nachdem ich nun beide Tabellen über INSERT in die neue Datenbank migriert habe, ändern sich auch die PrimaryKey-Werte in den Datensätzen der zu überwachenden Tabelle. Aus diesem Grund will ich den Inhalt des Feldes “primary_key_wert” in der Änderungsnachweistabelle aktualisieren und dort den aktuellen PrimaryKey der Datensätze in der Tabelle tfv03 ablegen.
Migration der zu überwachenden Tabelle, Triggerfunktion während des Vorganges deaktiviert:

INSERT INTO public.tfv03
  (
    Feld1, Feld2, uebernahme_pk_fv03, WeitereFelder
  )
  SELECT 
    FeldQ1, FeldQ2, uebernahme_pk_fv03, WeitereFelder
  FROM dblink('dbname=DB host=127.0.0.1 user=NUTZER password=PASSWORD',
              'SELECT 
                 FeldQ1a, FeldQ2a, pk_fv03, WeitereFelder
               FROM 
                 SCHEMA.tfv03 
                   INNER JOIN SCHEMA.tfvs1 ON pkFeld=fkFeld 
               WHERE 
                 pk_fv03 <> 0'
             ) 
  AS ausgabe
    (
      FeldZ1 varchar(1000), FeldZ2 integer, uebernahme_pk_fv03 integer, WeitereFelder
    );

Das Feld mit dem “alten” PrimaryKey hat den Namen “uebernahme_pk_fv03” und ist vom Typ integer, wie das Ursprungsfeld. Meinem “Denken” nach sollte folgende Anweisung das Feld “primary_key_wert” in der Tabelle tupda aktualisieren:

UPDATE public.tupda SET primary_key_wert = (select DISTINCT pk_fv03 FROM public.tfv03 WHERE public.tfv03.uebernahme_pk_fv03 = public.tupda.primary_key_wert AND aenderung_tabelle = 'tfv03') WHERE public.tupda.primary_key_wert <> 0 AND aenderung_tabelle = 'tfv03';

Leider funktioniert das Ganze nicht, da “primary_key_wert” nicht NULL sein darf und die Abfrage anscheinend keinen passenden Eintrag findet und den Versuch wie folgt beendet :confused:

ERROR:  null value in column "primary_key_wert" violates not-null constraint
DETAIL:  Failing row contains (1464622, NUTZER, 2014-12-01, 15:55:11.049525, tfv03, ListeBetroffenerFelder, NEUANLAGE, WerteVeränderung, null).
SQL-Status: 23502

Demnach gibt es (zumindest für einen Datensatz) keinen Wert in der Tabelle tfv03 für den aktuellen “alten” PrimaryKey oder ich bin bei der UPDATE-Anweisung auf dem falschen Pfad. Ich suche in der Tabelle tfv03 den passenden Wert zum aktuellen Datensatz in tupda für das Feld “primary_key_wert”, welcher ebenfalls in tfv03.uebernahme_pk_fv03 stehen müßte, um dann den aktuellen PrimaryKey zu übernehmen.

Zur Prüfung, ob es nicht zuordbare Datensätze gibt versuche ich es mit:

SELECT fv03.uebernahme_pk_fv03
FROM public.tfv03 AS fv03
LEFT JOIN public.tupda AS upda ON fv03.uebernahme_pk_fv03 = upda.primary_key_wert
WHERE upda.primary_key_wert IS NULL

zur Gegenprobe

SELECT fv03.uebernahme_pk_fv03
FROM public.tfv03 AS fv03
LEFT JOIN public.tupda AS upda ON fv03.uebernahme_pk_fv03 = upda.primary_key_wert
WHERE fv03.uebernahme_pk_fv03 IS NULL

In beiden Fällen kein Ergebnis, also müßten alle Datensätze einen “Partner” haben.

Ich hoffe meine Erklärung ist ausreichend und verwirrt nicht. :sunglasses:

Wenn ich jetzt den total falschen Weg eingeschlagen habe, bin ich auch auf Hinweise in dieser Richtung dankbar.

Gruß und Dank
Rainer

So auf die Schnelle würde ich sagen Du willst:

UPDATE public.tupda 
  SET primary_key_wert = tfv03.pk_fv03
from public.tfv03 
WHERE tfv03.uebernahme_pk_fv03 = tupda.primary_key_wert 
  AND tfv03.aenderung_tabelle = 'tfv03' 
  AND tupda.primary_key_wert <> 0 
  AND tupda.aenderung_tabelle = 'tfv03';

Der Vorschlag von castorp erscheint schon mal gut, allein schon wegen Korrelation ohne Subselect.
In Deinem 2. (gegen)Probeselect sieht es so aus, als ob Du die falsche Seite auf is Null prüfst.

Insgesamt scheint mir die ganze Turnerei mit den PK etwas fragwürdig, wieso behälst Du nicht wenigstens auf der Altseite auch die alten Keys?

Und wenn Du Vergleiche machst, wieso arbeitest Du einerseits mit <>0 und andererseits mit is null?
PK sollten immer not Null sein, also einen Wert haben.
Wieso schließt Du den Default Wert 0 bei Deinen Statements aus, hast Du den mal abgeprüft?
Und wenn Du ihn ausschließt, warum nicht überall?

Hallo castorp und pogomips,
vielen Dank für Eure Hinweise. Manchmal ist man leider auf dem “einen Auge blind”, welches die Lösung hätte sehen können. :rolleyes:

Die Lösung von castorp hat mein Problem beseitigt - Vielen Dank!

@pogomips: Der Vergleich <>0 macht insofern Sinn, weil das mein “Nulldatensatz” in der Tabelle ist, welchen ich in jeder Tabelle habe. Ich werde mir nach Deinem Hinweis meine Tabellen nochmals ansehen und bei Bedarf überarbeiten. Ich will die PrimaryKeys durch die Migration neu aufbauen, am Anfang der Entwicklung vor ungefähr 7 Jahren hatte ich nicht meinen heutigen Wissensstand und die “Lücken” will ich mit dem aktuellen Vorgang “ausbügeln” - auch bieten sich in der aktuellen Version neue Möglichkeiten und die will ich, soweit sie mir von Nutzen sind, auch anwenden.

Gruß Rainer