सिद्धांत 2 के साथ WHERE IN का उपयोग कैसे करें


124

मेरे पास निम्नलिखित कोड है जो मुझे त्रुटि देता है:

Message: Invalid parameter number: number of bound variables does not match number of tokens 

कोड:

public function getCount($ids, $outcome)
{
    if (!is_array($ids)) {
        $ids = array($ids);
    }
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb->add('select', $qb->expr()->count('r.id'))
       ->add('from', '\My\Entity\Rating r');
    if ($outcome === 'wins') { 
        $qb->add('where', $qb->expr()->in('r.winner', array('?1')));
    }
    if ($outcome === 'fails') {
        $qb->add('where', $qb->expr()->in('r.loser', array('?1')));
    }
    $qb->setParameter(1, $ids);
    $query = $qb->getQuery();
    //die('q = ' . $qb);
    return $query->getSingleScalarResult();
}

डेटा (या $ आईडी):

Array
(
    [0] => 566
    [1] => 569
    [2] => 571
)

DQL परिणाम:

q = SELECT COUNT(r.id) FROM \My\Entity\Rating r WHERE r.winner IN('?1')

1
मुझे लगता है कि यह अनुशंसित तरीका है docs.doctrine-project.org/projects/doctrine-dbal/en/latest/…
martin

जवाबों:


114

इस मुद्दे पर शोध करने में, मुझे कुछ ऐसा मिला जो इस मुद्दे पर चलने वाले और समाधान की तलाश में किसी के लिए भी महत्वपूर्ण होगा।

मूल पोस्ट से, कोड की निम्नलिखित पंक्ति:

$qb->add('where', $qb->expr()->in('r.winner', array('?1')));

सरणी के रूप में नामित पैरामीटर को लपेटने से बाध्य पैरामीटर संख्या समस्या होती है। इसे अपने एरे रैपिंग से हटाकर:

$qb->add('where', $qb->expr()->in('r.winner', '?1'));

इस मुद्दे को तय किया जाना चाहिए। यह डॉक्ट्रिन के पिछले संस्करणों में एक समस्या हो सकती है, लेकिन यह 2.0 के सबसे हाल के संस्करणों में तय हो गई है।


5
मुझे लगता $qb->expr()->in()है कि केवल डॉक्ट्रिन 2 ओआरएम में है, लेकिन डॉक्ट्रिन डीबीएएल में नहीं।
मार्टिन

3
$qb->expr()->in()वास्तव में DBAL में है
जेम्सहलसाल

344

सबसे आसान तरीका है कि खुद को एक पैरामीटर के रूप में बाँधकर:

$queryBuilder->andWhere('r.winner IN (:ids)')
             ->setParameter('ids', $ids);

41
न केवल लेकिन 2.1 से शुरू
Maciej Pyszy Augski

7
@ MaciejPyszyński +1। सबसे आसान तरीके अक्सर सबसे अच्छे होते हैं!
आंद्रेज ओउमियालोव्स्की

2
त्वरित उल्लेख: यह प्रति डिफ़ॉल्ट डिफ़ॉल्ट रूप से -> setParameter ('ids', $ ids) के साथ काम करता है लेकिन -> setParameters ('id' => $ id) के साथ नहीं। मुझे डिबगिंग के कुछ मिनट लगे।
लैरीडाहोस्टर

3
बनाने के लिए -> setParameters (...) के साथ काम करना है ->where('b.status IN (:statuses)') ->setParameters([ 'customerId' => $customerId, 'storeId' => $storeId, 'statuses' => [Status::OPEN, Status::AWAITING_APPROVAL, Status::APPROVED] ]);
जॉर्ज माइलोनस

5
मैं setParameterबल देने के लिए 3 Connection::PARAM_STR_ARRAY
वाँ

58

और स्ट्रिंग समाधान को पूरा करने के लिए

$qb->andWhere('foo.field IN (:string)');
$qb->setParameter('string', array('foo', 'bar'), \Doctrine\DBAL\Connection::PARAM_STR_ARRAY);

निश्चित रूप से मेरे लिए सबसे अच्छा समाधान :-)
फ्रांसेस्को Casula

3
यदि आप पूर्णांक नहीं स्ट्रिंग की एक सरणी है, तो भी \ Doctrine \ DBAL \ Connection :: PARAM_INT_ARRAY का उपयोग कर सकते हैं।
ओम


12

मुझे पता है कि यह एक पुरानी पोस्ट है लेकिन किसी के लिए मददगार हो सकती है। मैं ints के बारे में टिप्पणियों में पूछे गए सवाल को संबोधित करके @ डैनियल एस्पेंडिलर के जवाब को वोट और बढ़ाऊंगा

इंट के लिए इस काम को उचित तरीके से करने के लिए, सुनिश्चित करें कि ऐरे में मान टाइप इंट के हैं, आप पास करने से पहले इंट को टाइप कर सकते हैं ...

 $qb->andWhere('foo.field IN (:ints)');
 $qb->setParameter('ints', array(1, 2), 
 \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);

सिम्फनी 3.4 और सिद्धांत-बंडल में चयन / हटाने के लिए परीक्षण किया गया: 1.8


8

मुझे पता है कि ओपी का उदाहरण डीक्यूएल और क्वेरी बिल्डर का उपयोग कर रहा है, लेकिन मैं इस बात पर अड़ गया कि इसे नियंत्रक से या रिपॉजिटरी क्लास के बाहर कैसे करना है, इसलिए शायद यह दूसरों की मदद करेगा।

आप WHERE INनियंत्रक से इस तरह भी कर सकते हैं :

// Symfony example
$ids    = [1, 2, 3, 4];
$repo   = $this->getDoctrine()->getRepository('AppBundle:RepoName');
$result = $repo->findBy([
    'id' => $ids
]);

1
यह DQL का उपयोग किए बिना एक पूरी तरह से स्वीकार्य तरीका है, लेकिन उसका सवाल उसके DQL कोड के संदर्भ में था। वह सिर्फ एक साधारण से अधिक कर रहा है मुझे इन आईडी के आधार पर सभी चीजें दें।
spetz83

6

ऐसा करने का सबसे अच्छा तरीका है - खासकर यदि आप एक से अधिक शर्त जोड़ रहे हैं - यह है:

$values = array(...); // array of your values
$qb->andWhere('where', $qb->expr()->in('r.winner', $values));

यदि आपके मानों में तार समाहित हैं, तो आप एक सेट किए गए स्ट्रिंग के साथ सेटपैरमीटर विधि का उपयोग नहीं कर सकते, क्योंकि आपके उद्धरण बच जाएंगे!


6

इस तरह मैंने इसका उपयोग किया:

->where('b.status IN (:statuses)')
->setParameters([
                'customerId' => $customerId,
                'storeId'    => $storeId,
                'statuses'   => [Status::OPEN, Status::AWAITING_APPROVAL, Status::APPROVED]
            ]);

5

2016 के वर्ष में इसे कैसे करना है: https://redbeardtechnologies.wordpress.com/2011/07/01/doctrine-2-dql-in-statement/

उद्धरण:

यहाँ यह कैसे ठीक से करने के लिए है:

$em->createQuery(“SELECT users 
     FROM Entities\User users 
     WHERE 
         users.id IN (:userids)”)
->setParameters(
     array(‘userids => $userIds)
);

विधि setParametersदी गई सरणी को ले जाएगी और इसे "IN" स्टेटमेंट में उपयोग करने के लिए ठीक से फंसाएगी।


2
इससे मेरी समस्या हल हो गई (चारों ओर कोष्ठक :userids)
मिहई राउडुचानु

2

मैं पसंद करता हूं:

$qb->andWhere($qb->expr()->in('t.user_role_id', [
    User::USER_ROLE_ID_ADVERTISER,
    User::USER_ROLE_ID_MANAGER,
]));

0
->where($qb->expr()->in('foo.bar', ':data'))
            ->setParameter('participants', $data);

इसके साथ ही काम करता है:

 ->andWhere($qb->expr()->in('foo.bar', ':users'))
                ->setParameter('data', $data);

0

मैं इसी परिदृश्य से जूझता रहा जहाँ मुझे मूल्यों की एक सरणी के खिलाफ एक प्रश्न करना था।

निम्नलिखित ने मेरे लिए काम किया:

http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/dql-doctrine-query-language.html#where-clause

->andWhereIn("[fieldname]", [array[]])

ऐरे डेटा उदाहरण (स्ट्रिंग्स और पूर्णांक के साथ काम किया गया):

$ids = array(1, 2, 3, 4);

क्वेरी उदाहरण (जहां आपको इसकी आवश्यकता है, उसके लिए अनुकूल करें):

$q = dataTable::getInstance()
    ->createQuery()
    ->where("name = ?",'John')
    ->andWhereIn("image_id", $ids)
    ->orderBy('date_created ASC')
    ->limit(100);

$q->execute();

0

यह वर्षों बाद है, एक विरासत साइट पर काम कर रहा है ... मेरे जीवन के लिए मैं ->andWhere()या ->expr()->in()समाधान काम नहीं कर सका ।

अंत में डॉक्ट्रिन मंगोलोड-ओर्ब रेपो में देखा गया और कुछ बहुत ही चौकाने वाले परीक्षण मिले:

public function testQueryWhereIn()
{ 
  $qb = $this->dm->createQueryBuilder('Documents\User');
  $choices = array('a', 'b');
  $qb->field('username')->in($choices);
  $expected = [
    'username' => ['$in' => $choices],
  ];
  $this->assertSame($expected, $qb->getQueryArray());
}

यह मेरे लिए काम किया!

आप गथुब पर परीक्षण यहां पा सकते हैं । सभी प्रकार की बकवास को स्पष्ट करने के लिए उपयोगी है।

नोट: मेरा सेटअप Doctrine MongoDb ODM v1.0.dev का उपयोग कर रहा है जहां तक ​​मैं बाहर कर सकता हूं।

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