sql – 如何使用除`=`之外的其他运算符使DBIx :: Class连接表?

前端之家收集整理的这篇文章主要介绍了sql – 如何使用除`=`之外的其他运算符使DBIx :: Class连接表?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
概要

我有一张成对的物品表.我想自己加入,所以我可以在单个查询中检索对的双方.它是有效的sql(我认为),sqlite引擎实际上接受它,但我无法获取DBIx :: Class咬住项目符号.

最小的例子

  1. package Schema::Half;
  2. use parent 'DBIx::Class';
  3. __PACKAGE__->load_components('Core');
  4. __PACKAGE__->table('half');
  5. __PACKAGE__->add_columns(
  6. whole_id => { data_type => 'INTEGER' },half_id => { data_type => 'CHAR' },data => { data_type => 'TEXT' },);
  7. __PACKAGE__->has_one(dual => 'Schema::Half',{
  8. 'foreign.whole_id' => 'self.whole_id','foreign.half_id' => 'self.half_id',# prevIoUs line results in a '='
  9. # I'd like a '<>'
  10. });
  11.  
  12. package Schema;
  13. use parent 'DBIx::Class::Schema';
  14. __PACKAGE__->register_class( 'Half','Schema::Half' );
  15.  
  16. package main;
  17. unlink 'join.db';
  18. my $s = Schema->connect('dbi:sqlite:join.db');
  19. $s->deploy;
  20.  
  21. my $h = $s->resultset('Half');
  22. $h->populate([
  23. [qw/whole_id half_id data /],[qw/1 L Bonnie/],[qw/1 R Clyde /],[qw/2 L Tom /],[qw/2 R Jerry /],[qw/3 L Batman/],[qw/3 R Robin /],]);
  24. $h->search({ 'me.whole_id' => 42 },{ join => 'dual' })->first;

最后一行生成以下sql

  1. SELECT me.whole_id,me.half_id,me.data
  2. FROM half me
  3. JOIN half dual ON ( dual.half_id = me.half_id AND dual.whole_id = me.whole_id )
  4. WHERE ( me.whole_id = ? )

我试图使用DBIx :: Class join语法来获取<>操作符在dual.half_id和me.half_id之间,但尚未到目前为止.

我试过的东西

该文档提示sql :: Abstract-like语法.

我试着写这个has_one的关系:

  1. __PACKAGE__->has_one(dual => 'Schema::Half','foreign.half_id' => { '<>' => 'self.half_id' },});
  2.  
  3. # Invalid rel cond val HASH(0x959cc28)

stringref后面的直sql不会使它成为:

  1. __PACKAGE__->has_one(dual => 'Schema::Half','foreign.half_id' => \'<> self.half_id',});
  2.  
  3. # Invalid rel cond val SCALAR(0x96c10b8)

解决办法以及为什么他们对我来说不够

我可以通过复杂的search()调用获得正确的sql,并且没有定义的关系.这是非常难看的,(也)很多硬编码的sql.对于关系遍历的每个具体情况,它必须以不必要的方式模仿.

我可以通过添加一个other_half_id列并加入=来解决问题.显然是冗余数据.

我甚至试图通过专用视图添加它来避免所述冗余(CREATE VIEW AS SELECT *,opposite_of(side)AS dual FROM half …)而不是数据库模式,它的代码是冗余和丑陋的,moreso比基于search()的解决方法.最后我没有勇气让它工作.

希望sql

这是我正在寻找的那种sql.请注意,这只是一个例子:我真的希望通过关系完成,所以我可以使用它作为Half ResultSet访问器,除了一个search()的连接子句.

  1. sqlite> SELECT *
  2. FROM half l
  3. JOIN half r ON l.whole_id=r.whole_id AND l.half_id<>r.half_id
  4. WHERE l.half_id='L';
  5. 1|L|Bonnie|1|R|Clyde
  6. 2|L|Tom|2|R|Jerry
  7. 3|L|Batman|3|R|Robin

旁注

我真的很自信,在我的全面扩大的情况下,但我很确定这不是问题.我以这种方式保留这个简单的例子,因为它也有助于保持代码大小小.

我坚持加入/关系路径,而不是复杂的搜索(),因为我有多个用途的关联,我没有找到任何“一刀切”的搜索表达式.

迟到更新

两年后的Answering my own question年以来,它以前是一个缺少的功能,从那时起就已经实现了.

解决方法

对于那些仍然感兴趣的人,它终于实现了0.08192或更早. (我目前在0.08192)

一个正确的语法是:

  1. __PACKAGE__->has_one(dual => 'Schema::Half',sub {
  2. my $args = shift;
  3. my ($foreign,$self) = @$args{qw(foreign_alias self_alias)};
  4. return {
  5. "$foreign.whole_id" => { -ident => "$self.whole_id" },"$foreign.half_id" => { '<>' => { -ident => "$self.half_id" } },}
  6. });

引用:DBIx::Class Extended Relationships on fREW Schmidt’s blog在哪里我首先阅读它.

猜你在找的MsSQL相关文章