一些背景知识:我正在Laravel 5.6.33(带有sqlite 3的PHP 7.2)上构建应用程序。
所以我有一个奇怪的情况,在测试中我期望一个异常,但是它永远不会被抛出。因此,我进行了深入挖掘,发现如果数据库驱动程序为sqlite,Laravel不会在where子句中为无效/不存在的列引发异常。以下代码仅返回一个空集合,而不抛出异常。
\App\Tag::where('notAColumn', 'foo')->get();
它很奇怪,我检查了整个地方,看我的配置是否有问题,没有发现任何异常。 Debug设置为true等。我运行此代码以使用内存中的sqlite数据库测试应用程序。
我注意到的另一件事是,如果我使用whereRaw
而不是where
,则会按预期引发异常。因此,例如,以下引发异常。
\App\Tag::whereRaw('notAColumn = "foo"')->get();
有人知道为什么会这样吗?
答案 0 :(得分:1)
两个查询之间的区别是列名的(非)引号:
Tag::where('notAColumn', 'foo')->get();
// select * from "tags" where "notAColumn" = 'foo'
Tag::whereRaw("notAColumn = 'foo'")->get(); // Literals are wrapped in single quotes.
// select * from "tags" where notAColumn = 'foo'
如果在无法将其解析为标识符但允许使用字符串文字的情况下使用双引号引起来的关键字(例如:“ key”或“ glob”),则该令牌应理解为字符串文字而不是标识符。
因此SQLite会将Tag::where('notAColumn', 'notAColumn')->get();
解释为两个(相同)字符串的比较,因此返回表中的所有行。