【问题标题】:Make Laravel use MySQL default value on insert/update让 Laravel 在插入/更新时使用 MySQL 默认值
【发布时间】:2023-03-29 14:52:02
【问题描述】:

我注意到,在 Laravel 中(使用 $model->fill(Input::all()) 时,数据如何输入并不重要),空字段(表单中为空)以空字符串 ('') 的形式出现。这是有道理的,因为这就是它从浏览器传递到 HTTP 服务器再到 PHP 的方式。

问题在于,如果列是数字且具有 DEFAULT 值,或者是 NULLable,则从 Eloquent 生成的查询对于列的值具有 '',因此 MySQL 将其解释并输入为0 而不是默认列值或NULL。是我在这里做错了什么,还是我需要投入额外的工作(例如突变器)来检测这个空字符串并转换为 null 以实现我真正想要的?

当然我明白,从技术角度来看,Laravel 在不知道你的列是如何工作的情况下,不能仅仅假设空字符串意味着将 NULL 传递给 INSERT 查询,因为有时你真的想要将字段(特别是基于字符的字段)设置为空字符串,而不是 NULL

也就是说,我不想仅仅因为我使用$model->fill() 而为我的所有模型定义修改器,但是有什么我不知道我可以做的吗?


对于阅读本文的 MySQL 人员 - 如果通过 '',将数字字段设置为 0 是否正确?似乎它应该被视为NULL,因为它不是明确的0,但我想它可能是弱类型,将'' 等同于0,而不是更远的NULL

【问题讨论】:

标签: mysql laravel laravel-4 eloquent


【解决方案1】:

有一个非常简单的方法可以做到这一点,那就是使用array_filter

$input = array_filter(Input::all(), 'strlen');
$model->fill($input);

array_filter 将返回分配给它们的所有键。

此解决方案有一些注意事项:

  • strlen 已被使用,而不是 empty。这是因为empty 会导致其他项目(例如数字 0)也被取消设置。
  • 这意味着通过更新进行的编辑(例如完全清空文本框)将不会由您的应用程序完成,因此请明智地使用!

编辑:关于MySQL的问题,是的,这很正常。

mysql> SELECT CAST("tim?" AS SIGNED);
+------------------------+
| CAST("tim?" AS SIGNED) |
+------------------------+
|                      0 |
+------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS;
+---------+------+-------------------------------------------+
| Level   | Code | Message                                   |
+---------+------+-------------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: 'tim?' |
+---------+------+-------------------------------------------+

【讨论】:

  • 感谢您的回答。正如我所担心的那样,没有什么好办法让它神奇地工作。但是,我会找到一种方法将其合并到我的 BaseModel 类中,并以某种方式确定是否应该在 '' 上忽略给定字段,或者实际上将 '' 提供给 MySQL。
【解决方案2】:

对于要在某些字段上插入的 默认 值,请不要为这些字段显式设置值。

当您收到表单数据时,处理每个字段并决定您要为其中的哪些字段插入 默认 值。然后将它们从 insert into ... 语句中删除。

示例
表单字段field1_1field_2

如果两者都给出了有效的输入,那么你可以编写如下的sql语句:

insert into my_table values( field_1_value, field_2_value );

如果其中一个字段,比如field_2 没有有效输入,您仍然希望记录进入数据库表。然后像这样写sql语句:

insert into my_table( field_1 ) values( field_1_value );

执行此操作时,SQL 引擎将使用在插入语句中省略的字段上定义的默认值。

注意:仅当您在数据库表中创建或更改列时为列设置了 default someValue 时才有效。

【讨论】:

  • 是的,我明白,如果我正在制作自己的查询,我可以忽略我不想通过的字段。但是我受制于 Laravel PHP 框架的 ORM,它会从它获得的所有数据中生成一个查询。在我的表单中,所有字段都已指定(即使为空),这就是问题所在。感谢您尝试提供帮助。
猜你喜欢
  • 2015-05-24
  • 2016-01-31
  • 2013-10-19
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 2013-08-17
相关资源
最近更新 更多