INTRO
我正在处理复杂的表单,以便对相当大的数据库执行自定义查询。因为用户可以使用一个或多个字段进行搜索,所以我决定使条件动态化,例如:
my $where{};
if($some_param && some_param ne ''){
push @{ $attr->{join} }, { 'aref' => { 'a_deeper_ref' => 'a_much_deeper_ref' }};
$where->{a_much_deeper_ref.field} = [-and => $some_param, {'!=', undef}];
}
if($another_param && $another_param ne '') {
... # same thing: do the join > build the condition.
}
my $rs = $model->search ($where, $attr);
大约有40到50个字段,虽然我可以像上面那样解决大部分字段,但有些字段有点棘手......
**问题**
我将使用有问题的示例来使其更清晰。 Supose yuo有一个laboratory_exams
表,其中的行表明给定的主题/患者[subject
表的外键]已针对给定的临床检查进行了测试[clinical_exam
的外键table]并存储该测试的结果。
现在,当用户想知道哪些受试者已经接受过艾滋病毒和丙型肝炎检测,并且艾滋病毒检测结果为阴性,丙型肝炎检测结果为阳性;表单提交将创建一个包含exam_ids
和results
的数组,我可以在控制器中轻松检索
my $params = $c->req->parameters;
my @labexams = ref $params->{exam_ids} ? @{$params->{exam_ids}} : $params->{exam_ids};
my @results = ref $params->{results} ? @{$params->{results}} : $params->{results};
当然,当我尝试在循环数组的$where
哈希中保存条件时,它会覆盖前一个并且我最终只得到数组中的最后一个元素,因为......
foreach my $i (0 .. $#labexams){
$where->{'labexams.exam_id'} = $labexams[$i];
$where->{'labexams.result'} = $results[$i];
}
...而且我只是继续将条件写在' labexams.exam_id'或者' labexams.result',这是静态的。
请注意,我需要生成的SQL与
类似... WHERE (labexams.exam_id = $labexam[$i] AND labexams.result = $result[$i]) AND ... #repeat for every exam/result pair
实际问题
我怎样才能实现这一点?
答案 0 :(得分:0)
使用ResultSet搜索链功能,而不是自己构建复杂参数。
my $ rs = ResultSet('Foo') - > search(...); $ rs = $ rs-> search(...);
答案 1 :(得分:-1)
我最终为子查询构建了一个SQL表达式,并将其作为对$ where哈希的引用传递。像魅力< 3
一样工作 if ($params->{labexam} && $params->{labexam} ne '' ){
my @labexams = ref $params->{labexam} ? @{$params->{labexam}} : $params->{labexam};
my @labexam_res = ref $params->{labexam_result} ? @{$params->{labexam_result}} : $params->{labexam_result};
my $exp_sql;
push @{ $attr->{join} }, 'laboratory_exams';
foreach my $i (0 .. $#labexams){
if($i == 0) {
$exp_sql .= ' IN ';
} else {
$exp_sql .= ' AND laboratory_exams.subject_id IN ';
}
$exp_sql .= '(SELECT subject_id FROM laboratory_exams WHERE exam_id = "'.$labexams[$i].'" AND value = "'.$labexam_res[$i].'")';
$i++;
}
$where->{'laboratory_exams.subject_id'} = \$exp_sql;
}