Mam następujący kod, który daje mi błąd:
Message: Invalid parameter number: number of bound variables does not match number of tokens
Kod:
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();
}
Dane (lub $ ids):
Array
(
[0] => 566
[1] => 569
[2] => 571
)
Wynik DQL:
q = SELECT COUNT(r.id) FROM \My\Entity\Rating r WHERE r.winner IN('?1')
php
doctrine-orm
query-builder
Tjorriemorrie
źródło
źródło
Odpowiedzi:
Badając ten problem, znalazłem coś, co będzie ważne dla każdego, kto napotka ten sam problem i szuka rozwiązania.
Z oryginalnego posta następujący wiersz kodu:
Zawijanie nazwanego parametru jako tablicy powoduje problem z numerem powiązanego parametru. Usuwając go z opakowania tablicy:
Ten problem powinien zostać naprawiony. To mógł być problem w poprzednich wersjach Doctrine, ale został rozwiązany w najnowszych wersjach 2.0.
źródło
$qb->expr()->in()
jest tylko w Doctrine 2 ORM, ale nie w Doctrine DBAL.$qb->expr()->in()
jest rzeczywiście w DBALNajłatwiej to zrobić, wiążąc tablicę jako parametr:
źródło
->where('b.status IN (:statuses)') ->setParameters([ 'customerId' => $customerId, 'storeId' => $storeId, 'statuses' => [Status::OPEN, Status::AWAITING_APPROVAL, Status::APPROVED] ]);
setParameter
do forceConnection::PARAM_STR_ARRAY
i na zakończenie rozwiązanie string
źródło
Odkryłem, że pomimo tego, co wskazuje dokumentacja, jedynym sposobem, aby to zadziałało, jest następujący:
http://groups.google.com/group/doctrine-dev/browse_thread/thread/fbf70837293676fb
źródło
Wiem, że to stary post, ale może być pomocny dla kogoś. Zagłosowałbym i ulepszyłbym odpowiedź @Daniel Espendiller, odpowiadając na pytanie zadane w komentarzach na temat int
Aby to działało dla int we właściwy sposób, upewnij się, że wartości w tablicy są typu int, możesz wpisać rzut na int przed przekazaniem ...
Przetestowane pod kątem zaznaczania / usuwania w symfony 3.4 i pakiecie doctrine: 1.8
źródło
Wiem, że przykład OP używa DQL i konstruktora zapytań, ale natknąłem się na to, szukając, jak to zrobić z kontrolera lub poza klasą repozytorium, więc może to pomoże innym.
Możesz również zrobić
WHERE IN
z kontrolera w ten sposób:źródło
Najlepszym sposobem na to - zwłaszcza jeśli dodajesz więcej niż jeden warunek - jest:
Jeśli twoja tablica wartości zawiera ciągi, nie możesz użyć metody setParameter z implodowanym ciągiem, ponieważ twoje cudzysłowy zostaną zmienione!
źródło
Tak to wykorzystałem:
źródło
Stwierdziliśmy, jak to zrobić w 2016 roku: https://redbeardtechnologies.wordpress.com/2011/07/01/doctrine-2-dql-in-statement/
Zacytować:
Oto jak to zrobić poprawnie:
Metoda
setParameters
weźmie podaną tablicę i prawidłowo ją imploduje w celu użycia w instrukcji „IN”.źródło
:userids
)Wolę:
źródło
Współpracuje również z:
źródło
Zmagałem się z tym samym scenariuszem, w którym musiałem wykonać zapytanie dotyczące tablicy wartości.
Pracowały dla mnie:
http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/dql-doctrine-query-language.html#where-clause
Przykład danych tablicy (działał z ciągami znaków i liczbami całkowitymi):
Przykład zapytania (dostosuj do miejsca, w którym go potrzebujesz):
źródło
To jest lata później, pracując nad starszą witryną ... Za całe życie nie mogłem dostać
->andWhere()
lub->expr()->in()
roztworów roboczych.W końcu zajrzałem do Doctrine mongodb-odb repo i znalazłem kilka bardzo odkrywczych testów:
U mnie zadziałało!
Możesz znaleźć testy na github tutaj . Przydatne do wyjaśniania wszelkiego rodzaju bzdur.
Uwaga: Moja konfiguracja korzysta z Doctrine MongoDb ODM v1.0.dev, o ile mogę to zrozumieć.
źródło