Doctrine 2 का उपयोग करके कच्चे SQL निष्पादित करें


102

मैं डॉक्ट्रिन 2 का उपयोग करके कच्चे एसक्यूएल को निष्पादित करना चाहता हूं

मुझे डेटाबेस तालिकाओं को छोटा करने और डिफ़ॉल्ट परीक्षण डेटा के साथ तालिकाओं को आरंभ करने की आवश्यकता है।


2
वैसे, जब मैं स्वचालित डेटाबेस ग्रन्टवर्क करना चाहता हूं, जैसे mysqldumpपिछले डंप या ड्रॉपिंग टेबल से डेटा को लोड करना या लोड करना, मैं आमतौर पर उस काम के लिए एक शेल स्क्रिप्ट लिखता हूं और फिर Symfony2 भाषा में एक कार्य (या "कमांड") लिखता हूं। ) जो शेल स्क्रिप्ट को निष्पादित करता है। एक ORM का उद्देश्य, जैसा कि मैं इसे समझता हूं, दोहराए जाने वाले काम को अलग करना है, और यदि आप एक तालिका को काट-छाँट करने जैसा कुछ कर रहे हैं, तो मुझे नहीं लगता कि Doctrine को चित्र में लाने के बाद यह कैसे समझ में आएगा। t उस कार्य को कोई भी आसान बनाएं।
जेसन स्विट

जवाबों:


164

यहाँ Doctrine 2 में एक कच्ची क्वेरी का एक उदाहरण है जो मैं कर रहा हूँ:

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
अच्छा उत्तर। इस कोड में इकाई प्रबंधक पाने के लिए, आप "$ this-> getEntityManager ()" के ऊपर इस कोड के स्थान पर $ इस- getDoctrine () -> getManager () का उपयोग कर सकते हैं , इस तरह से इसने तुरंत काम किया।
वेबब्लोवर

हे इसके मुझे देने के लिए अपरिभाषित विधि सूचकांक को कॉल करें :: getDoctrine () मुझे क्या करना चाहिए
Dexter

सिद्धांत 2 के साथ CodeIgniter का उपयोग कर im wildlyinaccurate.com/integrating-doctrine-2-with-codeigniter-2
डेक्सटर

1
यह मुझे सही दिशा में ले गया, लेकिन वास्तव में मुझे इसकी आवश्यकता नहीं थी। मुझे संदेह है कि उत्तर की उम्र से फर्क पड़ता है। मैं प्रयोग किया है: ...getConnection()->query($sql);और चलाने के लिए नहीं था$stmt->execute();
ब्रैंडन

ध्यान दें कि Symfony4 और autowiring के साथ, आप संकेत टाइप कर सकते हैं EntityManagerInterface $entityManagerऔर फिर कॉल कर सकते हैं$entityManager->getConnection()
COIL

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

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

18
निष्पादन के बजाय तैयार () कॉल करने के लिए भी एक अच्छा विचार है ताकि आप अभी भी तैयार स्टेटमेंट समर्थन प्राप्त कर सकें।
जेरेमी हिक्स

44

मुझे ऐसा करने से काम मिला, यह मानते हुए कि आप पीडीओ का उपयोग कर रहे हैं।

//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 बदल सकते हैं।


1
उन सभी में से सबसे अच्छा उदाहरण
डेविड

14

कच्ची क्वेरी को कैसे निष्पादित करें और डेटा वापस करें।

अपने प्रबंधक पर हुक लगाएँ और एक नया कनेक्शन बनाएँ:

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

अपनी क्वेरी बनाएं और प्राप्त करें:

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

डेटा इस तरह से प्राप्त करें:

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

1
क्वेरी () के लिए है जब एसक्यूएल कुछ डेटा देता है जिसे आप उपयोग करना चाहते हैं; exec () तब के लिए है जब यह नहीं है
Jeffiekins

12

मुझे पता चला कि उत्तर शायद है:

NativeQuery आपको देशी एसक्यूएल निष्पादित करने देता है, अपने विनिर्देशों के अनुसार परिणामों की मैपिंग करता है। ऐसा विनिर्देश जो बताता है कि कैसे एक SQL परिणाम सेट को एक Doctrine परिणाम पर मैप किया जाता है, एक ResultSetMapping द्वारा दर्शाया जाता है।

स्रोत: मूल निवासी एसक्यूएल


17
यह स्वीकृत उत्तर है, लेकिन मैं अभी भी यह नहीं देखता कि डॉक्ट्रिन का यह भाग कैसे उपयोगी है क्योंकि आपको हमेशा ResultSetMapping की आवश्यकता होती है। मैं नहीं चाहता कि यह परिणाम निकाय संस्थाओं को दे। .... जो कि मनमाने ढंग से एसक्यूएल चलाने की बात को गलत ठहराती है!
माइकमेर्को

2
: @MikeMurko मैं सिद्धांत 2 में कच्चे क्वेरी चलाने के लिए इस पोस्ट उपयोगी पाया forum.symfony-project.org/viewtopic.php?f=23&t=37872
जेसन Swett

इसके अलावा गैर-मूल निवासी SQL हर संभव SQL क्वेरी को निष्पादित नहीं करेगा। DELETE / UPDATE / INSERT अभ्यस्त काम करते हैं, न ही कुछ तालिका परिभाषाएँ जो सिद्धांत धारणाओं का पालन नहीं करती हैं। (बिना आईडी के M2M जॉइनिंग टेबल)। तो यह उत्तर सार्वभौमिक नहीं है। न ही INSERTs अभ्यस्त काम के रूप में स्वीकार किया जाना चाहिए।
przemo_li

5

मुझे भी यही समस्या थी। आप इकाई प्रबंधक द्वारा दिए गए कनेक्शन ऑब्जेक्ट को देखना चाहते हैं:

$conn = $em->getConnection();

तब आप सीधे इसके विरुद्ध क्वेरी / निष्पादित कर सकते हैं:

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

Http://www.doctrine-project.org/api/dbal/2.0/doctrine/dbal/connection.html पर कनेक्शन ऑब्जेक्ट के लिए डॉक्स देखें


5

अपने मॉडल में कच्ची एसक्यूएल स्टेटमेंट बनाएं (उदाहरण नीचे दी गई तारीख के अंतराल का एक उदाहरण है जिसका मुझे उपयोग करना था लेकिन अपना स्थानापन्न करें। यदि आप एक निष्पादन जोड़ -> fetchall () से निष्पादित () कॉल कर रहे हैं।

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

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

    $stmt->execute();

4

आप नहीं कर सकते, सिद्धांत 2 कच्चे प्रश्नों की अनुमति नहीं देता है। ऐसा लग सकता है कि आप कर सकते हैं, लेकिन अगर आप कुछ इस तरह की कोशिश करते हैं:

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

सिद्धांत यह कहते हुए एक त्रुटि उत्पन्न करेगा कि DATE_FORMAT एक अज्ञात फ़ंक्शन है।

लेकिन मेरा डेटाबेस (mysql) उस फ़ंक्शन को जानता है, इसलिए मूल रूप से जो हैपनिंग है, डॉक्ट्रिन उस क्वेरी को पर्दे के पीछे (और आपकी पीठ के पीछे) पार्स कर रहा है और एक ऐसा एक्सप्रेशन ढूंढ रहा है, जो क्वेरी को अमान्य न समझे।

इसलिए अगर मेरी तरह आप डेटाबेस में एक स्ट्रिंग भेजना चाहते हैं और इसे इससे निपटने दें (और डेवलपर को सुरक्षा की पूरी जिम्मेदारी लेने दें), तो इसे भूल जाएं।

बेशक आप किसी तरह से या किसी अन्य की अनुमति देने के लिए एक एक्सटेंशन को कोड कर सकते हैं, लेकिन आप इसे करने के लिए mysqli का उपयोग करने के साथ-साथ बंद कर देते हैं और Doctrine को इसे ORM buisness छोड़ देते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.