Как выбрать с помощью DBIx :: Class? - PullRequest
4 голосов
/ 13 ноября 2009

Я начинаю с DBIx :: Class, и у меня есть подвыбор, который хотел быть в DBIx :: Class, но я запутался и не могу построить код.это:

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

Я прочитал, что DBIx :: Class не поддерживает подвыбор;это правда?Если так, что вы делаете в подобных ситуациях?

Ответы [ 5 ]

6 голосов
/ 14 ноября 2009

В соответствии с 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 использует при построении своих запросов, имеет новую функцию подзапроса с использованием -nest.

3 голосов
/ 13 ноября 2009

Не может ли это быть представлено как объединение?

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

Это предполагает, что у вас есть отношения в категории под названием «Радио». Если вы этого не сделаете, есть много документации, которая поможет вам настроить отношения и узнать, как выполнить объединения .

Что касается подзапросов, в кулинарной книге для самой последней версии написано, что они поддерживаются , но экспериментальные .

2 голосов
/ 13 ноября 2009

Ну, вы всегда можете предоставить скалярную ссылку для вставки литерального SQL, когда используете метод DBIC search(). Например:

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

Это то, что мне приходилось делать в прошлом, когда мне нужно было больше выразительности, чем было поддержано DBIC. Однако я не знаю, правильно ли это делать в этом случае.

0 голосов
/ 23 июля 2010

Подвыборы теперь являются экспериментальной функцией и полезны, если вам нужно разрешить их во время компиляции. Однако я считаю, что следующим подходом будет хороший подход:

  1. большинство подвыборов может быть выполнено как (более быстрое) соединение, поэтому используйте объединение там, где вы можете
  2. если это не удастся, создайте представление в базе данных и класс схемы для представления.
0 голосов
/ 17 ноября 2009

после некоторого боя с 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');

СЛЕДУЮЩИЙ (скрипт, чтобы заставить его работать)

#!/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: 

Это было не то, что я действительно хотел, но это ближайший, цель состоит в том, чтобы выбрать только те столбцы, которые я хочу ... возможно, я достигну этой цели

...