2015-04-23 40 views
1

我有一个复杂的SQL语句,我想在DBIx中使用。 因此,我没有把它建立为“抽象”的美学方式,而是想为这种特殊情况使用View(DBIx :: Class :: ResultSource :: View)。如何在DBIx :: Class视图中构建动态SQL查询

这里是从原来的DBI代码我查询:

SELECT a."key", CASE WHEN $language = '' 
      THEN a."default" ELSE $language END AS lan 
FROM foo.regionlang as a 
INNER JOIN foo."displayPageKeys" as b ON a."key" = b."key" 
WHERE a.regions LIKE '%,$region,%' 
    AND b."displayPage" = ? 
UNION 
SELECT a."key", CASE WHEN $language = '' 
      THEN a."default" ELSE $language END AS lan 
FROM foo.regionlang as a 
INNER JOIN foo."displayPageKeys" as b ON a."key" = b."key" 
WHERE regions like '%,0,%' 
    AND b."displayPage" = ? 

所以,在我看来,它看起来像这样:

__PACKAGE__->result_source_instance->is_virtual(1); 

__PACKAGE__->result_source_instance->view_definition(q[ 
SELECT a."key", CASE WHEN ? = '' 
      THEN a."default" ELSE ? END AS lan 
FROM foo.regionlang as a 
INNER JOIN foo."displayPageKeys" as b ON a."key" = b."key" 
WHERE a.regions LIKE '%,$region,%' 
    AND b."displayPage" = ? 
UNION 
SELECT a."key", CASE WHEN ? = '' 
      THEN a."default" ELSE ? END AS lan 
FROM foo.regionlang as a 
INNER JOIN foo."displayPageKeys" as b ON a."key" = b."key" 
WHERE regions like '%,0,%' 
    AND b."displayPage" = ? 
]); 

我试着使用绑定更换$语言打电话,我用我的查询中替换任何值:

my @transl_hashrefs = $self->{schema}->resultset('View::Translation') 
     ->search(
      {}, 
      { 
       result_class => 'DBIx::Class::ResultClass::HashRefInflator', 
       bind => [ 
          $langmap, 
          $langmap, 
          $display_page, 
          $langmap, 
          $langmap, 
          $display_page, 
         ], 
      }) 
     ->all; 

我应该指出,该查询被称为上的Postgres,所以工作SQL应该是这个样子:

SELECT a."key", CASE WHEN "lang1" = '' 
      THEN a."default" ELSE "lang1" END AS lan 
FROM foo.regionlang as a 
INNER JOIN foo."displayPageKeys" as b ON a."key" = b."key" 
WHERE a.regions LIKE '%,$region,%' 
    AND b."displayPage" = 'home' 
UNION 
SELECT a."key", CASE WHEN "lang1" = '' 
      THEN a."default" ELSE "lang1" END AS lan 
FROM foo.regionlang as a 
INNER JOIN foo."displayPageKeys" as b ON a."key" = b."key" 
WHERE regions like '%,0,%' 
    AND b."displayPage" = 'home' 

的问题是,我得的$语言(“语言1”的价值)以某种方式使用双引号(“”)在SQL中。这不工作使用绑定的方式,这是专为价值观,而不是我猜。

你也可以通过使用绑定VAR和访问他们喜欢的$ 1,$ 2等的视图。但即使如此,我也不能把价值放在双引号内。

为最有可能的,非常混乱的问题

对不起。我试图让它尽可能清楚。

任何帮助非常感谢!

欢呼

+1

我想知道,如果你需要的是更换'Q ['和'QQ ['(QQ允许可变插值),然后更换'?'和'$ language'。 – Vinbot

+0

感谢您的回复!我忘了提及:我已经尝试过qq。看起来DBIx在使用qq时不理解占位符:声明没有占位符绑定在/usr/local/share/perl5/DBIx/Class/Storage/DBI.pm行1889. at/usr/local/share/perl5/DBIx/Class/Schema.pm line 1077 – RandomAndy

+0

缩写dir DBIx :: Class是DBIC而不是DBIx,它是一个完整的命名空间。 –

回答

2

我也有类似的问题,即普通的观点并没有帮助(主要是因为如果你加入的视图到其它表,添加其他标准和限制接受的行中,结合可以得到夹杂了params

我最终选择的解决方案比您的需求复杂得多,但其根源是Ovid最近编写的一个称为DBIx :: Class :: Report的模块,它可能不在CPAN上,但它是在github,和他在这里概括它:http://blogs.perl.org/users/ovid/2015/03/dbixclassreport---generate-ad-hoc-dbic-classes-from-sql.html

有了这个,你可以动态CR用任意SQL消除该视图,因此可以插入在绑定中效果不佳的标识符,并且可以正常地为安全/性能绑定其余条件。

+0

这是一个非常好的主意,非常感谢!我一直在寻找这样的事情,所以我会试试它是否适合我。 – RandomAndy