Jalankan SQL mentah menggunakan Doctrine 2

102

Saya ingin menjalankan SQL mentah menggunakan Doctrine 2

Saya perlu memotong tabel database dan menginisialisasi tabel dengan data uji default.

Jiew Meng
sumber
2
Ngomong-ngomong, ketika saya ingin melakukan pekerjaan database otomatis, seperti melakukan mysqldumps atau memuat data dari dump sebelumnya atau menjatuhkan tabel, saya biasanya menulis skrip shell untuk pekerjaan itu dan kemudian menulis tugas (atau "perintah", dalam bahasa Symfony2 ) yang menjalankan skrip shell. Tujuan dari ORM, seperti yang saya pahami, adalah untuk mengabstraksi pekerjaan berulang, dan jika Anda melakukan sesuatu seperti memotong tabel, saya tidak melihat bagaimana masuk akal untuk membawa Ajaran ke dalam gambar karena Ajaran tidak melakukannya t membuat tugas itu lebih mudah.
Jason Swett

Jawaban:

164

Berikut adalah contoh kueri mentah di Doktrin 2 yang saya lakukan:

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();
}   
Jason Swett
sumber
4
Jawaban bagus. Untuk mendapatkan manajer entitas dalam kode ini, Anda dapat menggunakan $ this-> getDoctrine () -> getManager () sebagai pengganti kode ini di atas "$ this-> getEntityManager ()" , cara ini langsung bekerja untuk saya.
webblover
hei itu memberi saya Panggilan ke metode yang tidak ditentukan Indeks :: getDoctrine () apa yang harus saya lakukan
Dexter
Saya menggunakan codeigniter dengan doktrin 2 wildlyinaccurate.com/integrating-doctrine-2-with-codeigniter-2
Dexter
1
Ini membawa saya ke arah yang benar tetapi tidak persis seperti yang saya butuhkan. Saya menduga bahwa usia jawabannya membuat perbedaan. Saya menggunakan: ...getConnection()->query($sql);dan tidak harus lari$stmt->execute();
Brandon
Perhatikan bahwa dengan Symfony4 dan autowiring, Anda dapat mengetik petunjuk EntityManagerInterface $entityManagerdan kemudian menelepon$entityManager->getConnection()
COil
50
//$sql - sql statement
//$em - entity manager

$em->getConnection()->exec( $sql );
orourkedd
sumber
18
Juga ide yang bagus untuk memanggil prepared () daripada exec sehingga Anda masih bisa mendapatkan dukungan pernyataan yang sudah disiapkan.
Jeremy Hicks
44

Saya membuatnya bekerja dengan melakukan ini, dengan asumsi Anda menggunakan PDO.

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

Anda dapat mengubah FETCH_TYPE sesuai dengan kebutuhan Anda.

fernandodof
sumber
1
Contoh terbaik dari semuanya
David
14

Cara menjalankan Kueri mentah dan mengembalikan data.

Hubungkan ke manajer Anda dan buat koneksi baru:

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

Buat kueri Anda dan fetchAll:

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

Dapatkan data dari hasil seperti ini:

$this->appendStringToFile("first row foobar is: " . $result[0]['foobar']);
Eric Leschinski
sumber
1
query () adalah untuk saat SQL mengembalikan beberapa data yang ingin Anda gunakan; exec () adalah untuk ketika tidak
Jeffiekins
12

Saya menemukan jawabannya mungkin:

NativeQuery memungkinkan Anda menjalankan SQL asli, memetakan hasil sesuai dengan spesifikasi Anda. Spesifikasi yang menjelaskan bagaimana kumpulan hasil SQL dipetakan ke hasil Doktrin diwakili oleh ResultSetMapping.

Sumber: SQL Asli .

Jiew Meng
sumber
17
Ini adalah jawaban yang diterima tetapi saya masih tidak melihat bagaimana bagian dari Doktrin ini berguna karena Anda selalu membutuhkan ResultSetMapping. Saya tidak ingin itu memetakan hasil ke Entitas .... yang secara default titik menjalankan SQL sewenang-wenang!
MikeMurko
2
@MikeMurko Saya menemukan posting ini berguna untuk menjalankan kueri mentah di Doktrin 2: forum.symfony-project.org/viewtopic.php?f=23&t=37872
Jason Swett
Selain itu, SQL Native Non-native tidak akan mengeksekusi setiap kemungkinan kueri SQL. DELETE / UPDATE / INSERT tidak akan berfungsi, atau beberapa definisi tabel yang tidak mengikuti asumsi doktrin. (M2M bergabung dengan tabel tanpa id). Jadi jawaban ini tidak universal. Juga tidak boleh diterima karena INSERT tidak akan berfungsi.
przemo_li
5

Saya memiliki masalah yang sama. Anda ingin melihat objek koneksi yang disediakan oleh manajer entitas:

$conn = $em->getConnection();

Anda kemudian dapat meminta / mengeksekusi secara langsung terhadapnya:

$statement = $conn->query('select foo from bar');
$num_rows_effected = $conn->exec('update bar set foo=1');

Lihat dokumen untuk objek koneksi di http://www.doctrine-project.org/api/dbal/2.0/doctrine/dbal/connection.html

Toby Batch
sumber
5

Dalam model Anda, buat pernyataan SQL mentah (contoh di bawah ini adalah contoh dari interval tanggal yang harus saya gunakan tetapi gantikan milik Anda sendiri. Jika Anda melakukan panggilan SELECT add -> fetchall () ke execute ().

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

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

    $stmt->execute();
badzilla.dll
sumber
4

Anda tidak bisa, Doktrin 2 tidak mengizinkan kueri mentah. Sepertinya Anda bisa tetapi jika Anda mencoba sesuatu seperti ini:

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

Doktrin akan mengeluarkan kesalahan yang mengatakan bahwa DATE_FORMAT adalah fungsi yang tidak diketahui.

Tapi database saya (mysql) tahu fungsi itu, jadi pada dasarnya apa yang terjadi adalah Doctrine sedang mem-parsing kueri itu di belakang layar (dan di belakang Anda) dan menemukan ekspresi yang tidak dipahami, menganggap kueri itu tidak valid.

Jadi jika seperti saya Anda ingin dapat mengirim string ke database dan membiarkannya menanganinya (dan biarkan pengembang bertanggung jawab penuh atas keamanan), lupakan saja.

Tentu saja Anda dapat membuat kode ekstensi untuk mengizinkannya dalam beberapa cara atau yang lain, tetapi Anda sebaiknya menggunakan mysqli untuk melakukannya dan meninggalkan Doctrine untuk bisnis ORM itu.

Alexis Finn
sumber