4

我从 DBIx::Class 开始,我有一个想要在 DBIx::Class 中的子选择,但我很困惑,无法构建代码。

我的 MySQL 选择是这个:

Select name from tblCategory where id = (
    Select id from tblCategory where id = (
         Select id from tblRadio where name = "RFM"
    )
);

我读到 DBIx::Class 不支持子选择;真的吗?如果是这样,在这种情况下你会怎么做?

4

5 回答 5

6

根据DBIx::Class::Manual::Cookbook有一个新的子查询功能:

my $inside_rs = $schema->resultset('Radio')->search({ name => 'RFM' });

my $rs = $schema->resultset('Category')->search({
    id => { '=' => $inside_rs->get_column('id')->as_query },
});

它被标记为 EXPERIMENTAL 所以 YMMV。

但是还要注意,在构建查询时使用的SQL::AbstractwhichDBIx::Class确实具有使用 -nest 的新子查询功能。

于 2009-11-13T22:22:02.300 回答
3

这不能表示为连接吗?

my $rs = $schema->resultset('Category')->search(
    {   
       'Radio.name' => 'RFM' 
    },
    {   
        'join' => 'Radio'
    }   
);

这假设您在名为“Radio”的类别中有关系。如果您不这样做,那么有大量文档可以帮助您设置关系并学习如何执行连接

至于子查询,最新版本的食谱说它们是受支持的,但是是实验性的。

于 2009-11-13T16:12:14.277 回答
2

好吧,当你使用 DBIC 的search()方法时,你总是可以提供一个标量引用来插入文字 SQL。例如:

my $rs = $schema->resultset('Category')->search({ 
              id => \"(Select id from tblRadio where name = 'RFM')" 
});

当我需要比 DBIC 开箱即用支持的更多表现力时,这就是我过去必须做的事情。不过,我不知道在这种情况下这是否是“正确”的做法。

于 2009-11-13T15:35:09.200 回答
0

经过与 DBIC 的一番斗争,我最终赢了:P (是的!)

不得不重写一些东西,并且不得不忘记子选择并做好关系。

我知道这段代码并不代表最初的问题,但是如果我不得不重新全部重写,我将向您展示我的“项目”的另一部分,在那里我又遇到了其他困难。

接下来是我所做的:

DBIx::类模式

package DB::Esquema::Passwords;

use strict;
use warnings;

use base 'DBIx::Class';

__PACKAGE__->load_components("Core");
__PACKAGE__->table("Passwords");
__PACKAGE__->add_columns(
  "pswd",
  { data_type => "INT", default_value => undef, is_nullable => 0, size => 11 },
  "password",
  {
    data_type => "VARCHAR",
    default_value => undef,
    is_nullable => 1,
    size => 20,
  },
  "utilizadorid",
  { data_type => "INT", default_value => undef, is_nullable => 1, size => 11 },
);
__PACKAGE__->set_primary_key("pswd");
__PACKAGE__->belongs_to('utilizadorid' => 'DB::Esquema::Utilizadores');
#belongs_to is not autogenerated, done by hand

与 Utilizadores(用户)有关系

package DB::Esquema::Utilizadores;

use strict;
use warnings;

use base 'DBIx::Class';

__PACKAGE__->load_components("Core");
__PACKAGE__->table("Utilizadores");
__PACKAGE__->add_columns(
  "utilizador",
  { data_type => "INT", default_value => undef, is_nullable => 0, size => 11 },
  "nome",
  {
    data_type => "VARCHAR",
    default_value => undef,
    is_nullable => 1,
    size => 20,
  },
  "mail",
  {
    data_type => "VARCHAR",
    default_value => undef,
    is_nullable => 1,
    size => 30,
  },
);
__PACKAGE__->set_primary_key("utilizador");
__PACKAGE__->has_one('utilizador' => 'DB::Esquema::Passwords', 'utilizadorid');

NEXT(使其工作的脚本)

#!/usr/bin/perl -w

use strict;
use diagnostics; #was important to understand
use lib '/var/www/projectox/lib'; #is where the schema is
use DB::Esquema; #use the Schema

system('clear'); # clear the screen

my $esquema = DB::Esquema->connect("dbi:mysql:dbname=dbswiak","root","");
    $esquema->storage->debug(1);

    #HAD TO USE PREFETCH
    my $resultado = $esquema->resultset('Utilizadores')->search(
    undef,{
         prefetch => { 'utilizador' => 'utilizadorid' }
      }
    )->next();

结果:

    SELECT me.utilizador, me.nome, me.mail, utilizador.pswd, 
utilizador.password, utilizador.utilizadorid, utilizadorid.utilizador, utilizadorid.nome, utilizadorid.mail 
FROM Utilizadores me JOIN Passwords utilizador 
ON utilizador.utilizadorid = me.utilizador 
JOIN Utilizadores utilizadorid ON utilizadorid.utilizador = utilizador.utilizadorid: 

不是我真正想要的,而是最近的,目标是只选择我想要的列......也许我会达到那个目标

于 2009-11-17T18:00:33.303 回答
0

子选择现在是实验性功能,如果您需要在编译时允许它们,它很有用。但是我发现以下是一个很好的方法:

  1. 大多数子选择可以作为(更快的)连接完成 - 所以在你可以使用的地方使用连接
  2. 如果做不到这一点,请在数据库中创建一个视图并为该视图创建一个模式类。
于 2010-07-23T07:30:10.743 回答