【问题标题】:SQlite NOT throwing exceptions for unknown columns in where clauseSQlite 不会在 where 子句中为未知列抛出异常
【发布时间】:2018-09-29 12:40:00
【问题描述】:

一点背景知识:我正在 Laravel 5.6.33(PHP 7.2 和 sqlite 3)上构建一个应用程序。

所以我有一个奇怪的情况,在测试中我期待一个异常但它永远不会被抛出。所以我去挖掘发现,如果数据库驱动程序是 sqlite,Laravel 不会在 where 子句中为无效/不存在的列抛出异常。下面的代码只是返回一个空集合而不是抛出异常。

\App\Tag::where('notAColumn', 'foo')->get();

这很奇怪,我检查了所有地方,看看我的配置是否有问题,并没有发现任何不合适的地方。 Debug 设置为 true 等。我运行此代码以使用内存中的 sqlite 数据库测试应用程序。

我注意到的另一件事是,如果我使用whereRaw 而不是where,则会按预期抛出异常。所以例如下面的抛出一个异常。

\App\Tag::whereRaw('notAColumn = "foo"')->get();

有人知道为什么会这样吗?

【问题讨论】:

    标签: laravel laravel-5 sqlite


    【解决方案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'
    

    来自documentation

    如果双引号中的关键字(例如:“key”或“glob”)用于无法解析为标识符但允许字符串字面量的上下文中,则该标记被理解为字符串文字而不是标识符。

    因此 SQLite 会将 Tag::where('notAColumn', 'notAColumn')->get(); 解释为两个(相同)字符串的比较,因此返回表中的所有行。

    【讨论】:

    • 哇,我发现这太难以置信了。但看起来你很准。我使用 eloquent::toSql 方法来查看查询及其正是这个。有什么解决办法吗?我将 mariaDB 用于实际应用程序。 sqlite 测试让一些错误未被发现。尤其是在架构更改之后。
    • 您是否建议我使用 mysql 数据库进行测试?不过速度很慢。
    • 我真的没有看到解决方案。是的,我会建议这样做。使用不同的数据库测试您的代码可能会导致各种问题并隐藏潜在的错误。我知道很多人使用 SQLite 进行测试,但这绝对不是理想的。您的应用程序越复杂且以数据库为中心,您会发现这两个数据库之间的差异就越大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 2011-06-03
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多