Вопрос по php, sql-server-2008 – Доктрина 2. Не удается обновить столбец DateTime в SQL Server 2008apm.

6

Я использую Doctrine 2.2 с php 5.3 на сервере apache.

До сих пор я сталкивался со следующей проблемой: Когда я пытаюсь обновить столбец datetime, я получаю: SQLSTATE [22007]: [Microsoft] [Собственный клиент SQL Server 10.0] [SQL Server] Преобразование не выполнено при преобразовании даты и / или времени из символьной строки.

Я даже зашел так далеко, чтобы получить доступ к столбцу, а затем использовать его, добавив к нему всего 1 день, чтобы установить новую дату ...... тот же результат.

Когда я вместо этого изменяю и столбец в базе данных, и в сущности с даты на время, он функционирует как задумано.

Моя главная проблема в том, что есть несколько полей, в которых мне НУЖНО использовать столбец datetime.

Вот мой код:

(дата рождения была столбцом, который я изменил к дате .... и является одним из немногих столбцов, где это возможно для меня):

<code>//This returns the datetime object that represents birthdate from the database 
$help=$object->getBirthDate(); 
$help->setTimestamp(mktime($time[0],$time[1],$time[2],$date[2],$date[1],$date[0])); 
$help->format(\DateTime::ISO8601); 
$object->setBirthDate($help);
</code>

Кто-нибудь знает обходной путь здесь?

Ваш Ответ

4   ответа
8

ма в том, что поле базы данных имеет типDATETIME, но doctirne поддерживает толькоDATETIME2 на платформе SQLServer2008 и выше.

Вам не следует редактировать файлы в каталоге вашего поставщика. Правильный ответ - создать собственный тип: Doctrine Custom Mapping Types. В моем случае я расширил текущий DateTimeType:

<?php

namespace AppBundle\Doctrine\Type;

use Doctrine\DBAL\Types\DateTimeType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class DateTime extends DateTimeType
{
    private $dateTimeFormatString = 'Y-m-d H:i:s.000';

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return ($value !== null)
            ? $value->format($this->dateTimeFormatString) : null;
    }

}

А потом в Symfony config.yml:

    types:
      datetime: AppBundle\Doctrine\Type\DateTime
Чтобы применить этот класс вне Symfony (если используетсяdoctrine-orm напрямую), просто добавьuse Doctrine\DBAL\Types\Type; Type::overrideType(Type::DATETIME, 'YourNameSpace\DateTimeTypeSqlServer2012'); в любом месте вашего кода, прежде чем использовать какие-либо критерии с датами. Я добавил его в функцию, которая сгенерировала класс EntityManager, так что это своего рода постоянное исправление. shadi
Для тех, кто знаком с конфигом YAML доктрины в config.yml, в доктрину необходимо добавить тип: ключ: dbal: key. Loftx
6

которая должна быть исправлена в 2.3.

Микросекунды приводятся к строке с неправильным количеством нулей.

Workaround: измените функцию convertToDatabaseValue в файле /Doctrine/DBAL/Types/DateTimeType.php

public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
   if( $value === null)
      return null;

   $value = $value->format($platform->getDateTimeFormatString());

   if( strlen($value) == 26 &&
         $platform->getDateTimeFormatString() == 'Y-m-d H:i:s.u' &&
         ($platform instanceof \Doctrine\DBAL\Platforms\SQLServer2008Platform
          ||
         $platform instanceof \Doctrine\DBAL\Platforms\SQLServer2005Platform
         ) )
      $value = substr($value, 0, \strlen($value)-3);
   return $value;
}
Спустя 3 года, DBAL находится на уровне 2,5 ... и до сих пор не исправлено :( Мне также приходилось делать обходные пути, подобные этому, в Doctrine 1.x при использовании SQL Server. Здравствуйте? Высококачественные библиотеки вроде этого не заработают доверие к предприятию, если эти вещи не будут сглажены. Извините, что ругаюсь, но я один из тех, кто пытается продвигать OSS в основном в M $ магазине. Подобные проблемы НЕ помогают моему делу. DinoAmino
Как я могу избежать изменения файлов, которые находятся под Composer? Как я могу зарегистрировать свой собственный тип? przemo_li
Спасибо, это помогло мне исправить эту ошибку в одном из наших старых проектов. Marco Bax
@ DinoAmino Не знаю, поможет ли это вам сейчас, но посмотрите мой ответ о том, как решить эту проблему с помощью DBAL 2.5 David Legatt
0

Какую ценность ты пропускаешь вdatetime поле? Вы должны передатьDatetime экземпля

$entity->setDate(new \Datetime());
Да, я передаю экземпляр даты и времени. Я делаю следующее (дата рождения - это столбец, который я изменил до даты .... и это один из немногих столбцов, где это возможно для меня): $ help = $ object-> getBirthDate (); // Возвращает объект datetime, который представляет дату рождения из базы данных $ help-> setTimestamp (mktime ($ time [0], $ time [1], $ time [2], $ date [2], $ date [1]) , $ дата [0])); $ Help-> формат (\ DateTime :: ISO8601); $ Object-> setBirthDate ($ помощь); Thomas
0

Doctrine ORM v2.6.3 / DBAL v2.9.2. (для Doctrine Platform я используюSQLServer2012Platform).

Все, что вам нужно сделать, это изменить поля SQL сDATETIME вDATETIME2 тип (где это возможно)

Похожие вопросы