2010-05-05 40 views
40

Tengo algunas consultas extremadamente complejas que necesito usar para generar un informe en mi aplicación. Estoy usando Symfony como mi framework y mi doctrina como mi ORM.Uso de SQL sin procesar con Doctrine

Mi pregunta es la siguiente:

¿Cuál es la mejor manera de pasar en las consultas SQL altamente complejas directamente a la doctrina sin convertirlos al lenguaje de consulta Doctrina? He estado leyendo sobre la extensión Raw_SQL, pero parece que todavía necesita pasar la consulta en secciones (como from()). ¿Hay algo para simplemente deshacerse de un montón de comandos raw sql?

+0

Con permiso del fuera de tema, pero qué herramienta/biblioteca está utilizando para generar sus informes de aplicación? ¡Un cordial saludo! –

+2

¿Ahora mismo? Solo SQL, PHP sin formato y agallas. : D –

Respuesta

47
$q = Doctrine_Manager::getInstance()->getCurrentConnection(); 
$result = $q->execute(" -- RAW SQL HERE -- "); 

Consulte la documentación de la API Doctrina de diferentes métodos de ejecución.

+0

¿Esto funciona para actualizar el archivo también? – simple

+0

@simple: Sí, puede usar cualquier SQL que desee. – Tom

+7

Como esta respuesta parece ser popular, debo agregar que este método evita el escape ofrecido por Doctrine, así que escapa cosas manualmente o puedes dejarte abierto a agujeros de inyección de SQL. – Tom

38

Sí. Puede obtener un identificador de base de datos de Doctrina usando el siguiente código:

$pdo = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh(); 

y luego ejecutar el SQL de la siguiente manera:

las variables
$query = "SELECT * FROM table WHERE param1 = :param1 AND param2 = :param2"; 
$stmt = $pdo->prepare($query); 

$params = array(
    "param1" => "value1", 
    "param2" => "value2" 
); 
$stmt->execute($params); 

$results = $stmt->fetchAll(); 

Puede utilizar enlazados como en el ejemplo anterior.

Tenga en cuenta que Doctrine no hidratará sus resultados en objetos de registro, etc., por lo que deberá tratar los resultados devueltos como una matriz, que consiste en una matriz por fila devuelta (valor-clave como columna- valor).

+0

¿Hay alguna manera de forzar la doctrina para hidratar los resultados que obtengo a través de la DOP? o simplemente tengo que trabajar con lo que me dan? –

+0

De memoria cuando utilicé lo anterior, no automáticamente, ya que Doctrine no sabe qué columnas tiene. Si nombró las columnas lo suficientemente bien, supongo que podría utilizar fromArray() o similar, pero los datos tendrían que volver a formatearse en algo utilizable para eso. – richsage

+0

Si puede, use su consulta para devolver una ID de registro y luego use la antigua tabla $ table-> find ($ id) para cargarla. – lotsoffreetime

6

no estoy seguro de lo que quiere usted decir diciendo SQL prima, pero coud ejecutar consultas SQL tradicionales de esta manera:

... 
// $this->_displayPortabilityWarning(); 

$conn = Doctrine_Manager::connection(); 
$pdo = $conn->execute($sql); 
$pdo->setFetchMode(Doctrine_Core::FETCH_ASSOC); 
$result = $pdo->fetchAll(); 
... 

El siguiente método no es necsessary, pero muestra una buena práctica.

protected function _displayPortabilityWarning($engine = 'pgsql') 
{ 
    $conn = Doctrine_Manager::connection(); 
    $driver = $conn->getDriverName(); 

    if (strtolower($engine) != strtolower($driver)) { 
     trigger_error('Here we have possible database portability issue. This code was tested on ' . $engine . ' but you are trying to run it on ' . $driver, E_USER_NOTICE); 
    } 
} 
6

También puede usar Doctrine_RawSql(); para crear consultas SQL sin procesar que se hidratarán para doctrinar objetos.

6

Debe tenerse en cuenta que Doctrine2 usa PDO como base, por lo tanto, recomendaría utilizar sentencias preparadas sobre ejecución simple.

Ejemplo:

$db = Doctrine_Manager::getInstance()->getCurrentConnection(); 
$query = $db->prepare("SELECT `someField` FROM `someTable` WHERE `field` = :value"); 
$query->execute(array('value' => 'someValue')); 
+0

Esta pregunta es sobre Symfony 1. En Symfony 1, se usa Doctrine 1.2: esta respuesta podría ser errónea. – xmc

+0

Lo siento, no quise engañar. La solución aún es válida, ya que Symfony 1 también se puede usar con Doctrine. –

+1

+1 para el uso de ejemplo de preparación de consultas. –

0

Symfony insertar sql prima usando doctrina.

Esta versión en Symfoney 1,3

$q = Doctrine_Manager::getInstance()->getCurrentConnection(); 
$result = $q->execute($query); 
Cuestiones relacionadas