2

Hier ist ein vereinfachtes Beispiel Schema:PostgreSQL: Kann man eine Sitzungsvariable mit der Sprache definieren und in Sichten verwenden?

Table l10n (l10n_id SMALLINT, code VARCHAR(5)) 
Table product (product_id INT, ..language-neutral columns..) 
Table product_l10n (product_id INT, l10n_id SMALLINT, ..language-specific columns..)

für Produkte mit lokalisierten Daten abfragen, wie dies geschehen ist:

SELECT * 
    FROM product a 
     LEFT JOIN product_l10n b ON b.id = a.id 
     LEFT JOIN l10n c ON c.id = b.id 
    WHERE c.code = 'en-US';

dass große Fett Abfrage zu vermeiden, würde Ich mag Ansichten verwenden.
Die Grundidee besteht darin, eine Sicht basierend auf der obigen Abfrage ohne die Where-Klausel zu erstellen.
Querying für Produkte wäre dann:

SELECT * FROM product_view WHERE c.code = 'en-US';

Eine weitere Idee wäre, eine Variable zu haben, um die Sprach-Tag, definiert für jede DB-Verbindung/Sitzung enthält.
Die Ansicht würde auf der ersten Abfrage basieren, die die Variable in der WHERE-Klausel verwendet.
Die Variable wird in der aktuellen DB-Sitzung festgelegt, für Produkte Abfrage dann als dies so einfach wäre:

SELECT * FROM product_view;

Also meine Frage ist: Kann man das tun? Wie?

Es ist möglich, benutzerdefinierte Variablen in postgresql.conf verwenden. Siehe das Dokument Customized Options.

In postgresql.conf:

custom_variable_classes = 'myproject' 
    myproject.l10n_id = 'en-US'

Zu Beginn der DB-Sitzung (die param wird auf Session-Ebene standardmäßig eingestellt):

SET myproject.l10n_id = 'en-US';

In Ansichten:

WHERE c.code = current_setting('myproject.l10n_id')

Aber ... Ich mag es nicht, eine Variable für den gesamten Server zu definieren. Gibt es eine Möglichkeit, dasselbe zu erreichen, aber pro Datenbank?

Vielen Dank im Voraus,
Pascal

PS: Ich postes eine andere Frage haben in Bezug auf als SMALLINT mit l10n_id oder direkt als ISO-Code in einem VARCHAR (5). Siehe http: // stackoverflow.com/questions/1307087/how-to-store-sprache-tag-ids-in-datenbanken-as-smallint-or-varchar (sorry, nur 1 URL für neue Benutzer :-)

+0

Ich finde tatsächlich das Überschreiben einer globalen Einstellung, um reines Genie zu sein. Gute Abhilfe für die Ausnahme, die eine nicht definierte Variable verursacht. Ich setze Variablen für Sitzungslevel oft für diese Art von Dingen und wickle sie dann in Ausnahmen durch die Verwendung von benutzerdefinierten Funktionen. – whardier

Antwort

2

Nun, was genau ist das Problem mit der Erstellung der Variablen für den gesamten Server? Es beeinflusst keine andere Verbindung/Abfrage, also sollte es in Ordnung sein.

    :

    kann Ein weiterer Ansatz durch die Tatsache verwendet wird, dass jede Verbindung mit Back-End-pid gefunden werden kann, die mit

    select pg_backend_pid(); 
    

    So erhalten werden können, können Sie eine Tabelle mit Spalten wie erstellen

  • backend_pid int4
  • variable_name Text
  • variable_value Text

mit Primärschlüssel auf (backend_pid, Variablenname) und bieten eine Reihe von Funktionen, die den Wert erhalten und den Wert setzen, intern überprüfen pg_backend_pid.

Es gibt immer noch ein Problem, was passiert, wenn die Verbindung ohne "Aufräumen" schließt (alle Variablen werden entfernt), und neue Verbindung wird gestartet - Variablen aus der vorherigen Verbindung erhalten, aber das ist normalerweise nicht sehr wahrscheinlich.

Ich dachte ein wenig darüber nach, und schrieb blog post mit genauen SQL, die Tabelle und Funktionen erstellen, die erforderlich sind, damit es funktioniert.

+0

Ich habe es schließlich als benutzerdefinierte Variable definiert. Es gibt kein Problem damit. Nur finde ich das nicht wirklich sauber ;-) –

Verwandte Themen