Как правильно подойти к вопросу: yii1 в поля типа datetime вставляет значение по умолчанию «current_timestamp()» как строку. Как починить?

Ссылка скопирована
Yii
1 ответ

Сейчас ситуация такая: изначально писал не я, проект взял на вопровожденгие недавно.

Сейчас ситуация такая: добавляю запись, значения полей не указываю.
Выкидывает ошибку:
Сейчас ситуация такая: cDbCommand не удалось исполнить SQL-запрос: SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: current_timestamp()

Кусок DDL:
По вводным: date_create DATETIME DEFAULT CURRENT_TIMESTAMP,
По вводным: date_update DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Виктор Sys Ответ

В Yii1 проблема с current_timestamp() как строкой обычно появляется из-за того, что значение передаётся через ActiveRecord как обычная строка. ORM экранирует его и вставляет в SQL в кавычках, поэтому база получает текст 'current_timestamp()', а не функцию.

Если вы хотите, чтобы база сама подставляла текущее время, лучший вариант — задать default на уровне схемы таблицы и вообще не передавать это поле при вставке. Тогда MySQL/PostgreSQL применит значение по умолчанию сам.

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

Если значение нужно задать из Yii, используйте SQL expression, а не строку:

$model->created_at = new CDbExpression('CURRENT_TIMESTAMP');

$model->created_at = new CDbExpression('CURRENT_TIMESTAMP');

То же относится к update-полям:

$model->updated_at = new CDbExpression('CURRENT_TIMESTAMP');
$model->save(false);

$model->updated_at = new CDbExpression('CURRENT_TIMESTAMP'); $model->save(false);

Если это массовый insert/update через command builder, выражение тоже должно передаваться как CDbExpression, иначе оно будет экранировано. Не пытайтесь лечить это отключением экранирования или конкатенацией SQL из пользовательских данных — так легко получить SQL-инъекцию.

Также проверьте тип колонки. Для MySQL DATETIME и TIMESTAMP ведут себя немного по-разному. Если нужен автоматический update времени изменения, можно использовать:

updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Итог: если функция должна выполняться в базе, используйте default в схеме или new CDbExpression('CURRENT_TIMESTAMP'). Строка 'current_timestamp()' всегда будет сохранена как текст, потому что Yii1 делает ровно то, что должен делать ORM: безопасно экранирует значение.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно