Felder in einer Schleife durchlaufen

Moin liebes Forum,

ich habe mich mal an einer Funktion versucht, die mir nach einem Datenimport in eine bestehende DB meine Ursprungseinträge in einer Tabelle durch die entsprechenden IDs der Lookuptabelle ersetzt. Ich habe das bisher händisch gemacht.
Die Funktion läuft, aber ich könnte mir vorstellen, dass man sie optimieren kann, da die Statements alle gleich sind bis auf die Feldnamen. Lässt sich eine Schleife über alle Felder legen, so dass für jeden Datensatz alle Felder durchlaufen werden und das Update gemacht wird? Oder stehe ich gerade auf dem Schlauch und gehe falsch an die Sache heran?

Vielen Dank für Eure Hilfe.

Grüße, André

und hier die Funktion:

CREATE OR REPLACE FUNCTION gueteklasse_to_ids()
  RETURNS void AS
$BODY$
            declare
            ref RECORD;
	    
	   begin
              --Schleife über alle Messungen.
              for ref in select * from public.bio_mst_messungen where stat='neu'
                LOOP
		-- Messstellen und Messjahr eintragen. Weitere Spalten könnten ergänzt werden - geschieht jedoch später per Update.
                    update public.bio_mst_messungen bms Set phylib_diat_trophie = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib_diat_trophie::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set gk_fische_gesamt = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_fische_gesamt::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set perlodes_ad = (select id from wfd.quality_status_code qsc where qsc.value=ref.perlodes_ad::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set perlodes_sl = (select id from wfd.quality_status_code qsc where qsc.value=ref.perlodes_sl::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set sti_mp = (select id from wfd.quality_status_code qsc where qsc.value=ref.sti_mp::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set gk_sti_m = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_sti_m::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set gk_mp_gesamt = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_mp_gesamt::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set phylib_diatomeen = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib_diatomeen::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set gk_mzb_gesamt = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_mzb_gesamt::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set fibs = (select id from wfd.quality_status_code qsc where qsc.value=ref.fibs::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set gk_phytoplankton_gesamt = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_phytoplankton_gesamt::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set phytoplankton = (select id from wfd.quality_status_code qsc where qsc.value=ref.phytoplankton::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set perlodes = (select id from wfd.quality_status_code qsc where qsc.value=ref.perlodes::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set gk_sti_t = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_sti_t::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set phylib = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set phylib_makrophyten = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib_makrophyten::text) where bms.id = ref.id;
		    update public.bio_mst_messungen bms Set phylib_phytobenthos = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib_phytobenthos::text) where bms.id = ref.id;
                END LOOP;
            end
            $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

SQL in Schleifen ist faktisch immer FAIL, ich denke, auch hier. Ich hab aber grad wenig Lust, reverse zu erkunden,was Du da im Detail treibst. Da das WHERE immer gleich zu sein scheint dürfte das aber auch hier zutreffend sein.

Vielen Dank für Deine Antwort.

An sich läuft mein Code ja, aber ich hatte überlegt, dass es eventuell eleganter geht als 17 mal die selbe Zeile zu schreiben. Von der Idee her hätte ich die Variablennamen in ein Array geschrieben und dann in der Funktion nur noch

update public.bio_mst_messungen bms Set array[1]= (select id from wfd.quality_status_code qsc where qsc.value=ref.array[1]::text) where bms.id = ref.id;

Aber wenn es nicht machbar ist, kann ich auch mit der bestehenden Variante leben.

Zum Hintergrund des Ganzen: Ich kriege Daten verschiedenen Quellen als Excel-Sheets und überführe sie per CSV in eine postgresDB. Aus den Excel-Sheets kommen die Einträge für die in der Funktion betrachteten Felder als Integer mit Werten von 1 bis 5. In unserer Fachdatenbank sind die Güteklassen nicht direkt abgelegt sondern in einer Schlüsseltabelle und die ids der einzelnen Güteklassen sind 7 bis 11. Diese übersetze ich mit der Funktion.

Grüße,
André

Um die Angabe der Spaltenname wirst nicht drum herum kommen, aber schau Dir mal die Syntax von Update an:

Description: update rows of a table
Syntax:
[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    SET { column_name = { expression | DEFAULT } |
          ( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
    [ FROM from_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

und beachte, daß man da mehr als eine Spalte gleichzeitig updaten kann. Dadurch, daß Du 17 einzelne Updates machst, hast hinterher das 17-fache an toten Rows. Über Performance schweig ich mal.

Andreas

Danke für den Hinweis.
habe jetzt nur noch ein Update mit allen Spalten, sieht auf jeden Fall sauberer aus und ist wahrscheinlich auch performanter. Es müssen immer nur so 50-100 DS aktualisiert werden, da merkt man kaum, wenns schneller ist.
Grüße,
André

 begin
              --Schleife über alle Messungen.
              for ref in select * from public.bio_mst_messungen where stat='neu'
                LOOP
		-- Messstellen und Messjahr eintragen. Weitere Spalten könnten ergänzt werden - geschieht jedoch später per Update.
		update public.bio_mst_messungen bms Set phylib_diat_trophie = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib_diat_trophie::text),
			gk_fische_gesamt = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_fische_gesamt::text),
			perlodes_ad = (select id from wfd.quality_status_code qsc where qsc.value=ref.perlodes_ad::text), 
			perlodes_sl = (select id from wfd.quality_status_code qsc where qsc.value=ref.perlodes_sl::text),
			sti_mp = (select id from wfd.quality_status_code qsc where qsc.value=ref.sti_mp::text),
			gk_sti_m = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_sti_m::text),
			gk_mp_gesamt = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_mp_gesamt::text),
			phylib_diatomeen = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib_diatomeen::text),
			gk_mzb_gesamt = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_mzb_gesamt::text),
			fibs = (select id from wfd.quality_status_code qsc where qsc.value=ref.fibs::text),
			gk_phytoplankton_gesamt = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_phytoplankton_gesamt::text),
			phytoplankton = (select id from wfd.quality_status_code qsc where qsc.value=ref.phytoplankton::text),
			perlodes = (select id from wfd.quality_status_code qsc where qsc.value=ref.perlodes::text),
			gk_sti_t = (select id from wfd.quality_status_code qsc where qsc.value=ref.gk_sti_t::text),
			phylib = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib::text),
			phylib_makrophyten = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib_makrophyten::text),
			phylib_phytobenthos = (select id from wfd.quality_status_code qsc where qsc.value=ref.phylib_phytobenthos::text)
		where bms.id = ref.id;
                END LOOP;
            end

Vermutlich könnte man die äußere Schleife auch noch wegbekommen.

Solche performance-Killer merkt man bei Datenbanken immer erst, wenn es zu spät ist. Tägliche Erfahrung auf Arbeit. Du willst gar nicht wissen, was man mitunter zu sehen bekommt. Und das auch noch in MySQL, was in Hosting-Bereich nun mal (leider) fast nur eingesetzt wird.

sorry für die verspätete Antwort, ich war einige Tage unterwegs…
Die äußere Schleife ist mir auch ein kleiner Dorn im Auge, aber die Performance ist hier nicht ganz so wichtig, da ja wie oben gesagt nur ab und zu rel. wenige DS aktualisiert werden müssen. Ich habe auch eine vage Vorstellung, wie das ohne die Schleife aussehen müsste, aber mir fehlt neben dem notwendigen Wissen momentan die Zeit, mir selbiges anzueignen. Für mich läuft es so gut durch. Aber auf jeden Fall werde ich mir den Hinweis zu Herzen nehmen und bei der nächsten Funktion (die sicher kommt) mal von Grund auf versuchen, ohne Schleife auszukommen.
Also nochmals vielen Dank für Deine Hinweise und Tipps.
Grüße,
André