2012-05-10 14 views
5

Estoy usando Doctrine 2.2 con php 5.3 en un servidor apache.Doctrina 2: no se puede actualizar DateTime coloumn en SQL Server 2008apm

Hasta ahora ha tropezado con el siguiente problema: Cuando intento actualizar una columna de fecha y hora me sale: SQLSTATE [22007]: [Microsoft] [SQL Server Native Client 10.0] [SQL Server] Error de conversión al convirtiendo la fecha y/o hora de la cadena de caracteres.

Incluso he ido tan lejos para hacer una entrada en la columna y luego usar eso con solo 1 día agregado para establecer la nueva fecha ... el mismo resultado.

Cuando cambio tanto la columna en la base de datos como en la entidad desde la fecha hasta la fecha, funciona según lo previsto.

Mi problema principal es que hay algunos campos en los que NECESITO utilizar una columna de fecha y hora.

Aquí está mi código:

(fecha de nacimiento era la columna he cambiado hasta la fecha .... y es una de las pocas columnas cuando ello sea posible para mí):

//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); 

¿Alguien sabe una solución alternativa aquí?

Cualquier ayuda aquí es muy apreciada.

Respuesta

0

¿Qué valor está pasando al campo datetime? Debe pasar una instancia Datetime

$entity->setDate(new \Datetime()); 
+0

Sí estoy pasando una instancia de fecha y hora. Lo que hago es lo siguiente (fecha de nacimiento fue la columna que cambié hasta la fecha ...y es una de las pocas columnas donde eso es posible para mí): $ help = $ object-> getBirthDate(); // Esto devuelve el objeto datetime que representa la fecha de nacimiento de la base de datos $ help-> setTimestamp (mktime ($ time [0], $ time [1], $ time [2], $ date [2], $ date [ 1], $ fecha [0])); $ help-> format (\ DateTime :: ISO8601); $ object-> setBirthDate ($ help); – Thomas

6

Es un fallo oficial en Doctrina 2.2, para ser resuelto en 2.3.

Se están enviando microsegundos a la cadena con la cantidad incorrecta de ceros.

Solución: Cambiar la función convertToDatabaseValue en Archivo /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; 
} 
+4

Más de 3 años después, el DBAL está en 2.5 ... y todavía no hay solución :(También tuve que hacer soluciones como esta en Doctrine 1.x al usar SQL Server. Hola, las librerías de alta calidad como esta no ganarán credibilidad en la empresa a menos que se solucionen estas cosas. Perdón por despotricar, pero soy uno de los que intentan presionar por OSS en una tienda en gran parte M $. Problemas como este NO ayudan a mi caso. – DinoAmino

+0

¿Cómo puedo evitar cambiar archivos que están en Composer? ¿Cómo puedo registrar mi propio tipo? –

+0

Gracias, esto me ayudó a solucionar este error en uno de nuestros viejos proyectos. –

3

me encontré con este problema con Doctrina 2.5 y SQL Server 2012. El problema es que la base de datos campo es tipo DATETIME, pero doctirne solo es compatible con DATETIME2 en SQLServer2008Plataforma y más.

No debería estar editando archivos en su directorio de proveedores. La respuesta correcta es crear un tipo personalizado: Doctrine Custom Mapping Types. En mi caso, he ampliado la DateTimeType actual:

<?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; 
    } 

} 

Y luego en el config.yml Symfony:

types: 
     datetime: AppBundle\Doctrine\Type\DateTime 
+0

Para aplicar esta clase fuera de Symfony (si usa 'doctrine-orm' directamente), simplemente agregue' use Doctrine \ DBAL \ Types \ Type; Type :: overrideType (Type :: DATETIME, ' YourNameSpace \ DateTimeTypeSqlServer2012 '); 'en cualquier parte de ti código de r antes de usar cualquier criterio con fechas. Lo agregué en la función que generó la clase EntityManager, por lo que es una solución permanente. – shadi

Cuestiones relacionadas