将CAST(foo AS类型)作为DBIx :: Class中的关系条件传递

时间:2013-09-19 21:23:12

标签: perl postgresql dbix-class

由于历史原因,我们有一个工作表,在文本字段中具有与另一个表中的ID对应的整数值。例如:

CREATE TABLE things (
    id     INTEGER,
    name   VARCHAR,
    thingy VARCHAR
);

CREATE TABLE other_things (
    id     INTEGER,
    name   VARCHAR,
);

所以“东西”有一个“其他东西”,但是不是合理地设置,连接字段是一个varchar,称为“thingy”。

所以在Postgres中,我可以这样做来加入两个表:

SELECT t.id, t.name, ot.name FROM things t 
  JOIN other_things ot ON CAST(t.thingy AS int) = ot.id

如何在DBIx :: Class中表示此关系?这是我尝试过的一件事的例子:

package MySchema::Thing;

__PACKAGE__->has_one(
    'other_thing',
    'MySchema::OtherThing',
    { 'foreign.id' => 'CAST(self.thingy AS int)' },
); 

3 个答案:

答案 0 :(得分:4)

nwellnhof很接近,但是要将字面化的SQL转换为SQL :: Abstract,我必须像这样做一个coderef:

__PACKAGE__->has_one(
    'other_thing',
    'MySchema::OtherThing',
    sub {
        my $args = shift;
        return {
            qq{$args->{'foreign_alias'}.id} => { q{=} => \qq{CAST($args->{'self_alias'}.dept AS int)} },
        };  
    },
); 

答案 1 :(得分:3)

使用Literal SQL应该可以解决问题:

__PACKAGE__->has_one(
    'other_thing',
    'MySchema::OtherThing',
    { 'foreign.id' => { '=', \'CAST(self.thingy AS int)' } },
);

答案 2 :(得分:1)

我要更改字段的数据类型。

如果不可能,您可以添加另一个int类型的字段和一个将varchar转换为int的触发器,并将其存储在int字段中,然后将其用于连接以提高性能。