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

相关问题