Doctrine 2 kullanarak ham SQL yürütün


104

Doctrine 2'yi kullanarak ham SQL yürütmek istiyorum

Veritabanı tablolarını kesmem ve tabloları varsayılan test verileriyle başlatmam gerekiyor.


2
Bu arada, otomatik veritabanı gruntwork yapmak istediğimde, örneğin mysqldumpönceki dökümlerden veri yüklemek veya tabloları düşürmek gibi, genellikle o iş için bir kabuk komut dosyası yazıyorum ve sonra Symfony2 dilinde bir görev (veya "komut" yazıyorum) ) Kabuk betiğini çalıştıran. Bir ORM'nin amacı, anladığım kadarıyla, tekrar eden çalışmayı soyutlamaktır ve bir masayı kesmek gibi bir şey yapıyorsanız, Doktrini resme getirmenin ne kadar mantıklı olacağını anlamıyorum çünkü Doktrin bunu yapmaz. Bu görevi daha kolay hale getirin.
Jason Swett

Yanıtlar:


166

İşte Doctrine 2'de yaptığım bir ham sorgu örneği:

public function getAuthoritativeSportsRecords()
{   
    $sql = " 
        SELECT name,
               event_type,
               sport_type,
               level
          FROM vnn_sport
    ";

    $em = $this->getDoctrine()->getManager();
    $stmt = $em->getConnection()->prepare($sql);
    $stmt->execute();
    return $stmt->fetchAll();
}   

4
Güzel cevap. Bu kodda varlık yöneticisi almak için, "$ this-> getEntityManager ()" üzerindeki bu kod yerine $ this-> getDoctrine () -> getManager () kullanabilirsiniz , bu şekilde benim için hemen çalıştı.
webblover

hey bu bana veriyor Tanımlanmamış yönteme çağrı Index :: getDoctrine () ne yapmalıyım
Dexter

doktrin 2 ile kodlayıcı
Dexter

1
Bu beni doğru yöne götürdü ama tam olarak ihtiyacım olan şey değildi. Cevabın yaşının bir fark yarattığından şüpheleniyorum. Kullandım: ...getConnection()->query($sql);ve koşmak zorunda değildim$stmt->execute();
Brandon

Symfony4 ve otomatik kablolama ile ipucu EntityManagerInterface $entityManager$entityManager->getConnection()
yazıp

50
//$sql - sql statement
//$em - entity manager

$em->getConnection()->exec( $sql );

19
Ayrıca exec yerine ready () 'yi çağırmak iyi bir fikirdir, böylece yine de hazırlanmış ifade desteği alabilirsiniz.
Jeremy Hicks

45

PDO kullandığınızı varsayarak, bunu yaparak çalışmasını sağladım.

//Place query here, let's say you want all the users that have blue as their favorite color
$sql = "SELECT name FROM user WHERE favorite_color = :color";

//set parameters 
//you may set as many parameters as you have on your query
$params['color'] = blue;


//create the prepared statement, by getting the doctrine connection
$stmt = $this->entityManager->getConnection()->prepare($sql);
$stmt->execute($params);
//I used FETCH_COLUMN because I only needed one Column.
return $stmt->fetchAll(PDO::FETCH_COLUMN);

FETCH_TYPE’i ihtiyaçlarınıza göre değiştirebilirsiniz.


1
Hepsinden en iyi örnek
David

14

Ham bir sorgu nasıl çalıştırılır ve veriler nasıl döndürülür.

Yöneticinize bağlanın ve yeni bir bağlantı kurun:

$manager = $this->getDoctrine()->getManager();
$conn = $manager->getConnection();

Sorgunuzu oluşturun ve fetchAll:

$result= $conn->query('select foobar from mytable')->fetchAll();

Verileri sonuçtan şu şekilde alın:

$this->appendStringToFile("first row foobar is: " . $result[0]['foobar']);

1
query (), SQL'in kullanmak istediğiniz bazı verileri döndürdüğü zaman içindir; exec () olmadığı zamanlar içindir
Jeffiekins

12

Cevabın muhtemelen olduğunu öğrendim:

Bir NativeQuery, sonuçları spesifikasyonlarınıza göre eşleyerek yerel SQL'i çalıştırmanıza izin verir. Bir SQL sonuç kümesinin bir Doktrin sonucuna nasıl eşlendiğini açıklayan böyle bir belirtim, bir Sonuç Kümesi Eşleme ile temsil edilir.

Kaynak: Yerel SQL .


17
Kabul edilen cevap budur, ancak Doktrinin bu kısmının ne kadar yararlı olduğunu hala göremiyorum çünkü her zaman Sonuç-Kümesi Haritalamaya ihtiyacınız var. Sonuçları Varlıklar ile eşlemesini istemiyorum .... bu, rasgele SQL çalıştırma noktasını öntanımlı hale getirir!
MikeMurko

2
@MikeMurko Bu yazıyı Doctrine 2'de ham sorgular çalıştırmak için yararlı buldum: forum.symfony-project.org/viewtopic.php?f=23&t=37872
Jason Swett

Ayrıca Yerel Olmayan Yerel SQL, olası her SQL sorgusunu yürütmez. SİL / GÜNCELLE / EKLE çalışmaz, ne de doktrin varsayımlarına uymayan bazı tablo tanımları. (Kimlikleri olmayan M2M birleştirme tablosu). Yani bu cevap evrensel değil. INSERT'ler işe yaramayacağı için de kabul edilmemelidir.
przemo_li


5

Modelinizde ham SQL deyimini oluşturun (aşağıdaki örnek, kullanmam gereken ancak kendi tarih aralığının yerine geçecek bir tarih aralığı örneğidir. Execute () çağrısına bir SELECT add -> fetchall () yapıyorsanız.

   $sql = "DELETE FROM tmp 
            WHERE lastedit + INTERVAL '5 minute' < NOW() ";

    $stmt = $this->getServiceLocator()
                 ->get('Doctrine\ORM\EntityManager')
                 ->getConnection()
                 ->prepare($sql);

    $stmt->execute();

4

Yapamazsınız, Doctrine 2 ham sorgulara izin vermez. Yapabileceğin gibi görünebilir ama böyle bir şey denersen:

$sql = "SELECT DATE_FORMAT(whatever.createdAt, '%Y-%m-%d') FORM whatever...";
$em = $this->getDoctrine()->getManager();
$em->getConnection()->exec($sql);

Doktrin, DATE_FORMAT'ın bilinmeyen bir işlev olduğunu söyleyen bir hata verecektir.

Ancak veritabanım (mysql) bu işlevi biliyor, yani temelde olan şey, Doctrine'in bu sorguyu perde arkasında (ve arkanızda) ayrıştırması ve sorgunun geçersiz olduğunu düşünerek anlamadığı bir ifade bulmasıdır.

Yani benim gibi veritabanına basitçe bir dizge gönderebilmek ve bununla ilgilenmesine izin vermek (ve güvenlik için tüm sorumluluğu geliştiricinin almasına izin vermek) istiyorsanız, unutun.

Elbette bir uzantıyı bir şekilde buna izin verecek şekilde kodlayabilirsiniz, ancak bunu yapmak için mysqli'yi kullanıp Doctrine'i ORM işine bırakmanız daha iyi olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.