2

下面是模式的一個簡單的例子:PostgreSQL:可以用語言定義一個會話變量並在視圖中使用它嗎?

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..)

查詢產品的本地化數據就像下面這樣:

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';

爲了避免大胖子查詢,我想用意見。
其基本思路是基於上述查詢創建一個視圖,而不使用where子句。然後
查詢產品將成爲:

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

另一個想法是具有包含的語言標記,對於每個DB連接/會話定義的變量。
該視圖將基於在where子句中使用變量的第一個查詢。
變量在當前DB會話被設置,然後查詢產品會是如此簡單:

SELECT * FROM product_view;

所以我的問題是:一個做到這一點?怎麼樣?

在postgresql.conf中使用自定義變量是可行的。請參閱文檔Customized Options

postgresql.conf中:

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

在DB會話開始(帕拉姆設置爲默認會話級):

SET myproject.l10n_id = 'en-US';

在訪問量:

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

但是...我不喜歡爲整個服務器定義一個變量。有沒有一種方法可以實現相同的目標,但是要基於每個數據庫?

由於提前,
帕斯卡爾

PS:我postes使用l10n_id爲SMALLINT或直接作爲一個VARCHAR(5)的ISO代碼另一個問題有關。請參閱http:// stackoverflow.com/questions/1307087/how-to-store-language-tag-ids-in-databases-as-smallint-or-varchar (對不起,新用戶只有一個URL :-)

+0

其實我覺得一個全局設置的覆蓋是純粹的天才。對於未定義變量引起的異常很好的解決方法。我經常爲這類事情設置會話級變量,然後通過使用自定義函數將它們包裝到異常中。 – whardier 2014-04-10 20:55:27

回答

2

那麼,整個服務器變量的問題究竟是什麼?它不影響任何其他連接/查詢,所以它應該沒問題。

另一種方法可以通過一個事實,即每個連接可以使用後端進程,可以用

select pg_backend_pid(); 

因此獲得被發現使用,你可以創建一個表,與像列:

  • backend_pid INT4
  • 變量名文本
  • VARIABLE_VALUE文本

與(backend_pid,變量名)主鍵和提供一套該得到的值和設置的值的功能,在內部檢查pg_backend_pid。

還有一個問題,會發生什麼,如果連接關閉不使用「清理」(刪除所有變量),並且新的連接將開始 - 因此,從先前的連接變得變量,但是這通常是不太可能。

我想到一點關於它,並與將創建所需,使工作表和功能確切的SQL寫道blog post

+0

我最終將其定義爲自定義變量。 這沒有問題。這只是我沒有發現真的很乾淨;-) – 2009-10-15 11:32:16

相關問題