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::Abstractwhich DBIx::Classuses を使用すると、-nest を使用した新しいサブクエリ機能があることにも注意してください。

于 2009-11-13T22:22:02.300 に答える
3

これは結合として表すことができませんでしたか?

my $rs = $schema->resultset('Category')->search(
    {   
       'Radio.name' => 'RFM' 
    },
    {   
        'join' => '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 (YEAH!)

いくつかのものを書き直さなければならず、副選択を忘れて、関係をうまくやらなければなりませんでした。

このコードが最初の質問を表していないことは知っていますが、すべてを書き直す必要がある場合は、他の問題があった「プロジェクト」の他の部分を示しています。

次は私がやったことです:

DBIx::Classスキーマ

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');

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 に答える