RECORD durchlaufen

Hallo Leute,

ich habe hier ein kleines Problem und komme deswegen nicht weiter.

mydata RECORD;
sql text;

sql := '...';

FOR mydata IN EXECUTE(SELECT * FROM table) LOOP

     sql := sql || '...'; // hier das problem

END LOOP;

ich muss OHNE Spaltennamen (da Tabellen dynamisch sind) zu kennen, die Werte verbinden in einem String,
ungefähr so:

sql := mydata.spalte1 || ',' || mydata.spalte2, ....

Aber da ich die Spaltennamen nicht kenne, kann ich den RECORD nicht sinnvoll iterieren.

Gibt es da eine Möglichkeit ?

Danke vorraus!

  1. select * in produktivem Code ist arg böse
  2. du kannst die Spaltennamen auch dynamisch ermitteln
  3. je nach verwendeter PL kennt die Sprache auch die Spaltennamen. In PERL ist das IIRC z.B. der Fall


    Andreas

Ich will keine Spaltennamen ermitteln, ich brauche nur die Werte von dem Record (ohne Spaltennamen zu kennen),
geht das ?

Habe vergessen zu sagen,
der Code ist in ‘plpgsql’

Kommt auf die PL an.

Habe vergessen zu sagen,
der Code ist in ‘plpgsql’

In der nicht.


Andreas

Ich weiss jetzt nicht auf was sich deine Antwort bezieht.

Auf das man in Plpgsql auf die Spaltennamen von dem Record nicht kommt,
oder dass man Record ohne die zu wissen nicht durch iterieren kann.

Da mich nur der zweite Teil interessiert.

Angenommen ich habe ein RECORD mit Spaltenname:

rec.a = 10;
rec.b = 20;

Heisst das, dass ich nicht einfach irgendwie über Indexe

wie (Pseudocode)

rec[0], rec[1]

oder über

foreach(value in rec)
{
}

nicht auf die Werte komme ?

Bei Deiner Art zu quoten nicht verwunderlich.

Auf das man in Plpgsql auf die Spaltennamen von dem Record nicht kommt,
oder dass man Record ohne die zu wissen nicht durch iterieren kann.

Sowohl, als auch.

Da mich nur der zweite Teil interessiert.

Angenommen ich habe ein RECORD mit Spaltenname:

rec.a = 10;
rec.b = 20;

Heisst das, dass ich nicht einfach irgendwie über Indexe

wie (Pseudocode)

rec[0], rec[1]

oder über

foreach(value in rec)
{
}

nicht auf die Werte komme ?

Ja.

Andreas

Du kannst in pl/pgSQL nicht die Spaltennamen durch iterieren, das sieht die Sprache leider immer noch nicht vor.
Es gibt ein paar sehr krude Workarounds, aber die beinhalten ein paar weitere C-Module - und dann kann man auch gleich eine andere Sprache nehmen.

Wie würdet ihr dann folgendes realisieren ?

Es gibt eine Tabelle (mit dynamischen Anzahl und Namen von Spalten).
(Die Namen und Anzahl kann man aus den Metadaten der Datenbank auslesen)

Man muss diese Tabelle auslesen, Datensätze gruppieren und diese Daten in andere dynamische Tabelle mit gleicher Struktur speichern.

Auslesen und gruppieren ist einfach und funktioniert

DECLARE
    columns RECORD;
    sql_select text;

BEGIN

    -- SQL Query erstellen: SELECT avg(...) AS ..., avg(...) AS ..., avg(...) AS ... FROM tabele GROP BY kundennummer;
    -- Beispiel: SELECT avg(bilanz) AS bilanz, avg(anzahl) AS anzahl, avg(punkte) AS punkte FROM tabele GROP BY kundennummer;

    sql_select := 'SELECT ';

    FOR columns IN SELECT column_name FROM informations_schema.columns WHERE table_name = tablename LOOP
        sql_select := sql_select || 'avg(' || columns.column_name || ') AS ' || columns.column_name ' ,';
    END LOOP;

    sql_select := sql_select || 'FROM table GROUP BY kundennummer';

(PROBLEM) hier brauche ich eine INSERT query mit den Daten aus oberem SELECT

Ansatz wäre:

DECLARE
    data RECORD;

BEGIN

    -- SQL Query erstellen: INSERT INTO tabele (..., ..., ...) VALUES (..., ..., ...);
    -- Beispiel: INSERT INTO (bilanz, anzahl, punkte) VALUES (10, 20, 30);

    sql_insert := 'INSERT INTO tabele ';

    FOR data IN EXECUTE(sql_select) LOOP

        -- HIER PROBLEM (wie komme ich an die Werte der SELECT ? data."columns.column_name" geht ja leider nicht

    END LOOP;

PS:
Vorgehen wie
INSERT INTO table VALUES data,
also einfügen als komplettes RECORD geht nicht,
da ich dazwischen noch einige Berechnungen machen muss.


Danke im Voraus!

Nicht in pl/pgSQL …

Ok, verstehe… also im Grunde genommen ist klar.

Nur noch eine Frage zum Überlegen.

Wenn ich

RAISE NOTICE '%', data;

oben in der FOR schleife ausgeben lasse bekomme ich folgende Ausgabe:
z.B. je nach Tabelle:
(384,383.619995117188,1,4,1,1)

Das heisst ich komme an die Werte von dem Record doch ?
Ohne die Spalten zu kennen. Dann müsste man einfach die Klammer trimmen
und dann nach Komma Split machen.

Ist zwar riesen Hack und ich werde es so nicht machen. Aber nur als Überlegung…

Keine Ahnung, ob das geht.
Die Ausgabe wird von PostgreSQL generiert, nicht von pl/pgSQL.