Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 16

Thema: dynamisch Schema auswählen

  1. #1
    derLars ist offline Neuer Benutzer
    Registriert seit
    23.11.2009
    Beiträge
    11

    Standard dynamisch Schema auswählen

    Hallo allesamt,

    ich habe momentan folgende (stark vereinfachte) Tabellensituation. Ich habe eine Tabelle "persons" und "groups", die über einen Suchpfad sowohl in schema1 als auch in schema2 vorhanden sind. In den beiden Schemata getrennt vorhanden ist die Tabelle "dates".
    Diagramm1.jpg

    Ich muss nun eine Abfrage schreiben, die mir zu einer "persons_pk" über die Gruppennummer Start- und Enddatum aus der "dates"-Tabelle raussucht. Problem: In "group" gibt es die Spalte "use_schema", die eine 0 oder eine 1 enthalten kann. Je nach Inhalt soll entweder das schema1 oder das schema2 ausgewählt werden.

    Als Lösung hab ich mir eine Testfunktion gebaut, die das auslesen soll und dann die Tabelle zurückgeben soll:
    Code:
    CREATE OR REPLACE FUNCTION get_test () RETURNS char(32) AS '
        DECLARE
        BEGIN
            RETURN ''schema1.dates'';
        END;
    ' LANGUAGE 'plpgsql';
    
    SELECT
        persons.a,
        persons.b,
        groups.groups_pk,
        dates.start,
        dates.end
    FROM
        persons,
        groups,
        get_test(),
    WHERE
        persons.group_fk = groups.groups_pk AND
        groups.dates_fk = dates.dates_pk AND
        persons.persons_pk = 1234
    ;
    Leider klappt das so nicht ("dates" nicht gefunden). Hat jemand eine Lösung?

    Danke im Voraus!

  2. #2
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von derLars Beitrag anzeigen
    Hallo allesamt,

    ich habe momentan folgende (stark vereinfachte) Tabellensituation. Ich habe eine Tabelle "persons" und "groups", die über einen Suchpfad sowohl in schema1 als auch in schema2 vorhanden sind. In den beiden Schemata getrennt vorhanden ist die Tabelle "dates".
    Diagramm1.jpg

    Ich muss nun eine Abfrage schreiben, die mir zu einer "persons_pk" über die Gruppennummer Start- und Enddatum aus der "dates"-Tabelle raussucht. Problem: In "group" gibt es die Spalte "use_schema", die eine 0 oder eine 1 enthalten kann. Je nach Inhalt soll entweder das schema1 oder das schema2 ausgewählt werden.

    Als Lösung hab ich mir eine Testfunktion gebaut, die das auslesen soll und dann die Tabelle zurückgeben soll:
    Code:
    CREATE OR REPLACE FUNCTION get_test () RETURNS char(32) AS '
        DECLARE
        BEGIN
            RETURN ''schema1.dates'';
        END;
    ' LANGUAGE 'plpgsql';
    
    SELECT
        persons.a,
        persons.b,
        groups.groups_pk,
        dates.start,
        dates.end
    FROM
        persons,
        groups,
        get_test(),
    WHERE
        persons.group_fk = groups.groups_pk AND
        groups.dates_fk = dates.dates_pk AND
        persons.persons_pk = 1234
    ;
    Leider klappt das so nicht ("dates" nicht gefunden). Hat jemand eine Lösung?

    Danke im Voraus!
    Der Ansatz über eine Funktion ist richtig, der Weg aber falsch.

    Erst einmal:
    Was soll das einklich? Du machst Dir das Leben unnötig schwer. Verwende eine Tabelle, fertig ist. Willst Du auf diese Weise Partitionierung? Das geht anders. Und einfacher.

    Okay.

    Das, was Du willst, ist ein dynamisch generiertes (und ausgeführtes) SQL. Dafür hat die Doku Beispiele:
    PostgreSQL: Documentation: Manuals: PostgreSQL 8.4: Basic Statements

    In kurz: Du hast, zur Laufzeit, Dir das passende SQL zurecht zu friemeln und diese Gefriemel, ähm, SQL, dann auszuführen. Alles andere kann der Planner nicht planen, daher klappt das bei Dir auch nicht wie gewollt.

    In lang: überdenke Deine Idee.


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  3. #3
    ads
    ads ist offline Super-Moderator
    Registriert seit
    08.02.2006
    Ort
    MD
    Beiträge
    4.020

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    In lang: überdenke Deine Idee.
    Das ist eigentlich die kurze - und richtige - Aussage.
    Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören

    Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

    PostgreSQL Service & Support

  4. #4
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von ads Beitrag anzeigen
    Das ist eigentlich die kurze - und richtige - Aussage.
    Ja ;-)

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  5. #5
    derLars ist offline Neuer Benutzer
    Registriert seit
    23.11.2009
    Beiträge
    11

    Standard

    Hallo Andreas,

    ich habe ein fertiges Produkt mit einer unsäglich schrecklichen Datenbankstruktur, dass ich so hinbiegen muss, dass es für uns funktioniert. Das System kann nur einen Zeitrhythmus gleichzeitig abbilden, wir brauchten aber zwei - daher der Trick mit zwei Schemata und dem Suchpfad, der dann je nach benötigtem Schema angepasst wird.

    Mein Problem ist, dass die Abfrage in Wirklichkeit etwa 50 Spalten zurückholt und ich die nicht alle in eine Funktion packen und zurückgeben lassen will. Gibt es keine elegantere Lösung für dieses simple IF..ELSE -Problem?

  6. #6
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von derLars Beitrag anzeigen
    Hallo Andreas,

    ich habe ein fertiges Produkt mit einer unsäglich schrecklichen Datenbankstruktur, dass ich so hinbiegen muss, dass es für uns funktioniert. Das System kann nur einen Zeitrhythmus gleichzeitig abbilden, wir brauchten aber zwei - daher der Trick mit zwei Schemata und dem Suchpfad, der dann je nach benötigtem Schema angepasst wird.

    Mein Problem ist, dass die Abfrage in Wirklichkeit etwa 50 Spalten zurückholt und ich die nicht alle in eine Funktion packen und zurückgeben lassen will. Gibt es keine elegantere Lösung für dieses simple IF..ELSE -Problem?
    Vielleicht mit einem VIEW, der mittels UNION ALL aus den 2 Tabellen eine macht.

    Aber vielleicht wäre es einfacher, das 'Rodukt' zu fixen. Ads macht Dir bestimmt gerne ein Angebot ;-)


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  7. #7
    derLars ist offline Neuer Benutzer
    Registriert seit
    23.11.2009
    Beiträge
    11

    Standard

    Hi Andreas,

    dann hätte ich zwar alle Daten aus beiden Schemata drin (wenn ich deine Idee richtig verstehe), müsste aber die richtigen Daten immer noch über eine IF..ELSE o.Ä. rausfiltern - wobei ich das dann wieder in eine Funktion auslagern könnte... hmmm.... ich lass es mir mal durch den Kopf gehen, danke für die Hilfe.

    Produkt fixen ist leider nicht drin wegen späterer Updateproblematik vom Hersteller.

  8. #8
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von derLars Beitrag anzeigen
    Hi Andreas,

    dann hätte ich zwar alle Daten aus beiden Schemata drin (wenn ich deine Idee richtig verstehe), müsste aber die richtigen Daten immer noch über eine IF..ELSE o.Ä. rausfiltern - wobei ich das dann wieder in eine Funktion auslagern könnte... hmmm.... ich lass es mir mal durch den Kopf gehen, danke für die Hilfe.
    Nun ja, man kann ja auch mal tricksen:

    Code:
    test=*# create table lars1 (id int, value text);
    CREATE TABLE
    test=*# create table lars2 (id int, value text);
    CREATE TABLE
    test=*# insert into lars1 values (1, 'lars1');
    INSERT 0 1
    test=*# insert into lars1 values (2, 'lars2');
    INSERT 0 1
    test=*# create view view_lars as select 'table lars1' as tablename, id, value from lars1 union all select 'table lars2', id, value from lars2;
    CREATE VIEW
    test=*# select * from view_lars ;
      tablename  | id | value
    -------------+----+-------
     table lars1 |  1 | lars1
     table lars1 |  2 | lars2
    (2 rows)
    Nun hast Du im VIEW ein Selektionsmerkmal.


    Produkt fixen ist leider nicht drin wegen späterer Updateproblematik vom Hersteller.
    Hersteller in die Weichteile treten?


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  9. #9
    ads
    ads ist offline Super-Moderator
    Registriert seit
    08.02.2006
    Ort
    MD
    Beiträge
    4.020

    Standard

    Oder eine zweite Lizenz vom Hersteller kaufen.
    Oder Hersteller treten. Oh, hatten wir schon, den Ansatz.

    Wenn du mit Views arbeitest, kriegst du auch ein Problem bei den Updates. Die musst du alle entfernen, bevor irgendwas aktualisiert wird. Andernfalls könnte das Update fehlschlagen.
    Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören

    Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

    PostgreSQL Service & Support

  10. #10
    derLars ist offline Neuer Benutzer
    Registriert seit
    23.11.2009
    Beiträge
    11

    Standard

    Hallo Andreas,
    hallo ads,

    ich verstehe nicht ganz, wie die VIEW mein Problem lösen würde. Ich benötige als Rückgabe aus der Abfrage eine Spalte mit dem namen "startdate" und eine mit "enddate", und zwar je nach flagfeld entweder aus Schema1 oder aus Schema2. Sowas hier würde mich ja erstmal nicht weiter bringen:

    Code:
    CREATE DATABASE mytest;
    
    CREATE TABLE groups (
        groups_pk     INT PRIMARY KEY,
        schemeflag     SMALLINT NOT NULL,
        dates_fk     INT NOT NULL
        );
    
    CREATE SCHEMA schema1
        CREATE TABLE schema1.dates (
            dates_pk     INT PRIMARY KEY,
            startdate     DATE NOT NULL,
            enddate     DATE NOT NULL
            );
    
    CREATE SCHEMA schema2
        CREATE TABLE dates (
            dates_pk     INT PRIMARY KEY,
            startdate      DATE NOT NULL,
            enddate     DATE NOT NULL
            );
    
    INSERT INTO schema1.dates VALUES
        (1, '2009-01-01', '2009-05-31'),
        (2, '2009-06-01', '2009-12-31');
    
    INSERT INTO schema2.dates VALUES
        (1, '2009-01-01', '2009-03-31'),
        (2, '2009-04-01', '2009-07-30'),
        (3, '2009-08-01', '2009-12-31');
    
    INSERT INTO groups VALUES
        (1111, 1, 2),    -- linked to scheme1
        (2222, 2, 2);    -- linked to scheme2
    
    SELECT
        groups.*,
        schema1.dates.startdate AS s1start,
        schema1.dates.enddate AS s1end,
        schema2.dates.startdate AS s2start,
        schema2.dates.enddate AS s2end
    FROM
        groups,
        schema1.dates,
        schema2.dates
    WHERE
        groups.dates_fk = schema1.dates.dates_pk AND
        groups.dates_fk = schema2.dates.dates_pk
        ;
    
    -- Resultat:
     groups_pk | schemeflag | dates_fk |  s1start   |   s1end    |  s2start   |   s2end
    -----------+------------+----------+------------+------------+------------+------------
          1111 |          1 |        2 | 2009-06-01 | 2009-12-31 | 2009-04-01 | 2009-07-30
          2222 |          2 |        2 | 2009-06-01 | 2009-12-31 | 2009-04-01 | 2009-07-30
    Die View würde mir ja auch nicht mehr zurückgeben, nur auf Zeilen aufgeteilt - oder versteh ich das falsch?
    Geändert von derLars (12.01.2010 um 15:02 Uhr)

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum