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:
Leider klappt das so nicht ("dates" nicht gefunden). Hat jemand eine Lösung?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 ;
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
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
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
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
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?
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
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.![]()
Nun ja, man kann ja auch mal tricksen:
Nun hast Du im VIEW ein Selektionsmerkmal.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)
Hersteller in die Weichteile treten?
Produkt fixen ist leider nicht drin wegen späterer Updateproblematik vom Hersteller.![]()
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
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
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:
Die View würde mir ja auch nicht mehr zurückgeben, nur auf Zeilen aufgeteilt - oder versteh ich das falsch?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![]()
Geändert von derLars (12.01.2010 um 15:02 Uhr)
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen