2010-05-05 20 views
40

Ich habe einige sehr komplexe Abfragen, die ich verwenden muss, um einen Bericht in meiner Anwendung zu generieren. Ich benutze Symfony als meinen Rahmen und meine Lehre als mein ORM. dieseVerwenden von Raw SQL mit Doctrine

ist Meine Frage:

Was ist der beste Weg in hochkomplexen SQL-Abfragen Lehre direkt zu übergeben, ohne sie in die Lehre Query Language zu konvertieren? Ich habe über die Raw_SQL Erweiterung gelesen, aber es scheint, dass Sie noch die Abfrage in Abschnitten (wie from()) übergeben müssen. Gibt es etwas, um nur ein paar rohe SQL-Befehle zu speichern?

+0

Entschuldigen Sie die Wegthema

aber welches Werkzeug/Bibliothek verwenden Sie die Anwendung Berichte zu generieren? Mit freundlichen Grüßen! –

+2

Gerade jetzt? Nur SQL, Roh-PHP und Galle. : D –

Antwort

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

die Dokumentation Lehre API Siehe für verschiedene Ausführungsmethoden.

+0

Funktioniert das auch für die Aktualisierung des Feldes ??? – simple

+0

@simple: Ja, Sie können jedes gewünschte SQL verwenden. – Tom

+7

Da diese Antwort populär zu sein scheint, sollte ich hinzufügen, dass diese Methode die von Doctrine angebotene Entweichen umgeht, also stopfen Sie Dinge manuell oder Sie können sich für SQL-Injektionslöcher öffnen. – Tom

38

Ja. Sie können eine Datenbank-Handle aus Lehre mit dem folgenden Code erhalten:

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

und führen Sie Ihre SQL wie folgt:

$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(); 

Sie gebundene Variablen wie im obigen Beispiel verwenden können.

Beachten Sie, dass Doctrine Ihre Ergebnisse nicht automatisch in Datensatzobjekte usw. hydratisiert. Daher müssen Sie die zurückgegebenen Ergebnisse als Array behandeln, das aus einem Array pro zurückgegebener Zeile besteht (Schlüsselwert als Spalte). Wert).

+0

Gibt es eine Möglichkeit Lehre zu zwingen, die Ergebnisse, die ich über das PDO erhalten, um Hydrat? oder muss ich nur mit dem arbeiten, was mir gegeben wurde? –

+0

Aus dem Gedächtnis, wenn verwendete ich den oben, nicht automatisch als Lehre nicht weiß, welche Spalten Sie haben. Wenn Sie die Spalten gut genug Namen, ich denke, man fromArray() oder ähnliches verwenden könnte, aber die Daten müssten neu formatiert in etwas Brauchbares für das werden. – richsage

+0

Wenn Sie können, um Ihre Abfrage eine Datensatz-ID zurückzukehren und dann nur alte Tabellen- $ verwenden> find ($ id) zu laden. – lotsoffreetime

6

Ich bin mir nicht sicher, was meinst du sagen raw SQL, aber Sie coud traditionelle SQL-Abfragen auf diese Weise ausführen:

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

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

Die folgende Methode nicht necsessary ist, aber es zeigt eine gute Praxis.

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

Sie können auch Doctrine_RawSql(); um rohe SQL-Abfragen zu erstellen, die auf Doktrin-Objekte hydratisieren.

6

Es sollte beachtet werden, dass Doctrine2 verwendet PDO als Basis, so würde ich mit Prepared Statements über plain old ausführen empfehlen.

Beispiel:

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

Diese Frage bezieht sich auf Symfony 1. Auf Symfony 1 wird Doctrine 1.2 verwendet - Diese Antwort könnte irreführend sein. – xmc

+0

Entschuldigung, ich wollte nicht in die Irre führen. Die Lösung ist jedoch weiterhin gültig, da Symfony 1 auch mit Doctrine verwendet werden kann. –

+1

+1 für die Beispielverwendung der Vorbereitung der Abfrage. –

0

Symfony raw SQL einfügen Lehre verwenden. Diese in Version Symfoney 1,3

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