我从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不支持subselect;真的吗?如果是这样,你在这样的情况下做了什么?
答案 0 :(得分:5)
根据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 },
});
它标记为实验,所以YMMV。
但是请注意SQL::Abstract
DBIx::Class
在构建查询时使用的{{3}}确实有一个使用-nest的新子查询功能。
答案 1 :(得分:3)
这不能表示为连接吗?
my $rs = $schema->resultset('Category')->search(
{
'Radio.name' => 'RFM'
},
{
'join' => 'Radio'
}
);
这假设您在名为“Radio”的类别中有关系。如果不这样做,那么有大量文档可帮助您设置relationships并了解如何执行joins。
对于子查询,最新版本的食谱说它们是supported,但是experimental。
答案 2 :(得分:2)
嗯,当您使用DBIC的search()
方法时,您总是可以提供标量引用来插入文字SQL。例如:
my $rs = $schema->resultset('Category')->search({
id => \"(Select id from tblRadio where name = 'RFM')"
});
这就是我过去需要做的事情,当我需要比DBIC支持开箱即用更具表现力的时候。但我不知道,在这种情况下,这是否是“正确”的事情。
答案 3 :(得分:0)
不得不重写一些东西,不得不忘记子选择并很好地完成关系。
我知道这段代码并不代表一个正面的问题,但如果我不得不重新编写所有内容,我会向你展示我的“项目”的另一部分,在那里我又有了其他的困难。
接下来是我所做的:
DBIx :: Class Schema
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
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');
#!/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:
不是我真正想要的,但它是最近的,目标是只选择我想要的列...也许我会达到那个目标
答案 4 :(得分:0)
子选择现在是实验性功能,如果您需要能够在编译时允许它们,则它们非常有用。但是我发现以下是一个很好的方法。
(1)大多数子选择可以作为(更快)连接完成 - 所以尽可能使用连接 (2)如果失败,请在数据库中创建一个视图,并为视图创建一个模式类。