【问题标题】:STR_TO_DATE giving an error instead of nullSTR_TO_DATE 给出错误而不是 null
【发布时间】:2026-01-29 04:45:01
【问题描述】:

我正在从 csv 文件中获取数据并将其全部放入临时表中,因此所有内容都是字符串格式。

所以即使是日期字段也是字符串格式,所以我需要将日期从字符串转换为日期。所有日期都采用这种格式 28/02/2013

我为此使用了 STR_TO_DATE,但我遇到了问题。 这是我的代码的 sn-p。

INSERT INTO `invoice` (`DueDate`)
SELECT 
STR_TO_DATE('','%d/%m/%Y')
FROM `upload_invoice`

当然还有比这更多的领域,但我专注于不起作用的领域。 如果日期无效,则使用此命令应输入 null,但不是输入 null,而是生成错误。

#1411 - Incorrect datetime value: '' for function str_to_date

我了解错误的含义。这意味着它得到一个空字段而不是正确格式化的日期,但是在阅读文档后它不应该抛出错误,而是应该插入一个空值。

但是,如果我使用不带 INSERT 的 SELECT 语句,它会起作用。

我可以做下面这行,它确实有效

IF(`DueDate`!='',STR_TO_DATE(`DueDate`,'%d/%m/%Y'),null) as `DueDate`

因此,如果该字段为空,则 STR_TO_DATE 不会运行。现在这可行,但它无法检查无效的日期,例如日期是否为 ASDFADFAS。

然后我尝试了

IF(TO_DAY(STR_TO_DATE(`DueDate`,'%d/%m/%Y') IS NOT NULL),STR_TO_DATE(`DueDate`,'%d/%m/%Y'),null) as `DueDate`

但这仍然会在 if 语句中出现 #1411 错误。

所以我的问题是为什么 STR_TO_DATE 不在错误的日期返回 NULL?我不应该收到 #1411 错误。

这不是另一个问题的完全重复。也没有令人满意的答案。我解决了一段时间,并添加了我的解决方案,这实际上是另一篇文章中给出的更好的解决方案,所以我认为由于我的答案更好,这应该保留。

【问题讨论】:

标签: mysql date


【解决方案1】:

您可以尝试的选项:

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.19    |
+-----------+
1 row in set (0.00 sec)

mysql> DROP TABLE IF EXISTS `upload_invoice`, `invoice`;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `invoice` (
    ->   `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->   `DueDate` DATE
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `upload_invoice` (
    ->   `DueDate` VARCHAR(10)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `upload_invoice`
    ->   (`DueDate`)
    -> VALUES
    ->   ('ASDFADFAS'), (NULL), (''),
    ->   ('28/02/2001'), ('30/02/2001');
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> INSERT INTO `invoice`
    -> SELECT
    ->   NULL,
    ->   IF(`DueDate` REGEXP '[[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{4}' AND
    ->      UNIX_TIMESTAMP(
    ->        STR_TO_DATE(`DueDate`, '%d/%m/%Y')
    ->     ) > 0,
    ->   STR_TO_DATE(`DueDate`, '%d/%m/%Y'),
    ->   NULL)
    -> FROM `upload_invoice`;
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SELECT `id`, `DueDate`
    -> FROM `invoice`;
+----+------------+
| id | DueDate    |
+----+------------+
|  1 | NULL       |
|  2 | NULL       |
|  3 | NULL       |
|  4 | 2001-02-28 |
|  5 | NULL       |
+----+------------+
5 rows in set (0.00 sec)

db-fiddle

【讨论】:

  • 其实我很久以前就解决了这个问题,但忘了我已经发布了这个问题。我会发布我的答案。
【解决方案2】:

我忘了我发布了这个问题,但我不久前就这样解决了这个问题

IF(`{$date}`!='',STR_TO_DATE(`{$date}`,'%d/%m/%Y'),null) as `{$date}`

因此,由于行长且令人困惑,我制作了这样的函数

protected function strDate($date){
    return "IF(`{$date}`!='',STR_TO_DATE(`{$date}`,'%d/%m/%Y'),null) as `{$date}`";
}

INSERT INTO `invoice` (`DueDate`)
SELECT 
{$this->strDate('DueDate')}
FROM `upload_invoice`

我真的忘记了我发布了这个问题。这似乎是永恒的事,但这就是我解决问题的方法。

【讨论】:

    最近更新 更多