我正在尝试使用Laravel查询构建器实现相当复杂的SQL查询,我相信我可能遇到了一个错误 . 我想先确认你的情况 .
这是错误的代码:
public function getWordTranslations($word) {
if (strpos($word, '*') === false) {
$word .= '%';
} else {
$word = str_replace('*', '%', $word);
}
return $this->createTranslationQuery()
->whereIn('t.NamespaceID', function ($query) use($word) {
$tertiaryMatches = DB::table('keywords as k')
->join('translation as t', 'k.TranslationID', '=', 't.TranslationID')
->where('k.NormalizedKeyword', 'like', $word)
->where('t.Deleted', '=', 0)
->whereNotNull('k.TranslationID')
->select('t.NamespaceID');
$query->select('NamespaceID')
->from('keywords')
->where('NormalizedKeyword', 'like', $word)
->whereNotNull('NamespaceID')
->union($tertiaryMatches);
})->get();
}
createTranslationQuery
使用 DB
来创建查询构建器对象 . 我想用 IN
子查询过滤原始查询 .
不幸的是, whereIn
构建器生成的子查询不会使用单引号包装 $word
所持有的值 .
$word = "sample"
时的预期结果:
select ... where t.NamespaceID in(
select NamespaceID
from ...
where NormalizedKeyword like 'sample%'
...)
实际结果:
select ... where t.NamespaceID in(
select NamespaceID
from ...
where NormalizedKeyword like sample%
...)
=严重破损 .
这是例外(对于缺少格式化而道歉!):
SQLSTATE [42000]:语法错误或访问冲突:1064 SQL语法中有错误;查看与您的MySQL服务器版本对应的手册,以便在'union附近使用正确的语法(在关键字中选择t.NamespaceID作为k内连接转换'(SQL:选择w.Key作为Word,t.TranslationID,t .Translation,t.Etymology,t.Type,t.Source,t.Comments,t.Tengwar,t.Phonetic,l . Name as Language,t.NamespaceID,l . 发明为LanguageInvented,t.AuthorID,a.Nickname as authorName,w.NormalizedKey,t.Index,t.DateCreated,t.TranslationGroupID,tg.Name as TranslationGroup,tg.Canon,tg.ExternalLinkFormat,t.Uncertain,t.ExternalID from translation as t inner join word as w on t.WordID = w.KeyID内连接语言为l on t.LanguageID = l.ID left join auth_accounts as on t.AuthorID = a.AccountID left join translation_group as tg on t.TranslationGroupID = tg.TranslationGroupID where(t . 最新= 1和t.Deleted = 0)和t.NamespaceID in((从NormalizedKeyword中选择NamespaceID,如laiquendi%和NamespaceID不为null)union(选择t.Namespa) ceid从关键字作为k内连接转换为t on k.TranslationID = t.TranslationID其中k.NormalizedKeyword如laiquendi%和t.Deleted = 0且k.TranslationID不为null)))
这是一个错误,还是我做错了什么?
Edit #1
如果我删除了union指令,那么查询就会起作用,所以我怀疑是由于我使用的是与提供给 whereIn
方法的查询生成器不同的查询生成器而出现的错误 .
1 回答
我简化了解决方案 . 避免复杂性再次成功的关键 .