Може ли php PDO да извлече два набора от резултати? И ако да, какво е по-добре 1 набор от резултати или повече от 1?

Ако е възможно, как мога да извлека два набора от резултати:

$sth=$dbh->prepare("SELECT * FROM tb1 WHERE cond1;
                    SELECT * from tb2 Where cond2");
$sth->execute();
$row=$sth->fetchAll();  print_r ($row);

Това са две напълно различни таблици (няма общи полета).


person silversky    schedule 02.08.2013    source източник
comment
За какво трябва да извлечете 2 набора резултати в едно изявление?   -  person Your Common Sense    schedule 02.08.2013
comment
#Вашият здрав разум: Можете ли да преформулирате въпроса си на английски.   -  person silversky    schedule 02.08.2013
comment
@silversky Мисля, че е доста очевидно какво пита. Защо трябва да извличате 2 набора резултати в едно изявление?   -  person Mike    schedule 02.08.2013
comment
Е, защото мисля, че е по-добре да донесете в едно „пътуване“ всички резултати, от които се нуждаете   -  person silversky    schedule 02.08.2013
comment
Може първо да попитате дали така е по-добре?   -  person Your Common Sense    schedule 03.08.2013
comment
@Your Common Sense Току-що редактирах въпроса   -  person silversky    schedule 03.08.2013
comment
Кратък отговор: Не. PDO няма да изпълнява 2 заявки в 1 execute(). Дори ако човек просто зададе променлива. Няма причина да правите това също, вие не увеличавате производителността, спестявате време или сте умни.   -  person Sammitch    schedule 03.08.2013
comment
Да, PDO може да извлече два (или повече) набора редове. Дадох пример в отговора си по-долу.   -  person Nigel Alderton    schedule 04.02.2014


Отговори (6)


Да PDO може да извлече два (или повече) набора редове, стига базата данни, която използвате, да го поддържа. Мисля, че и MS SQL Server, и MySQL поддържат тази функционалност, но към момента на писане SQLite не го поддържа.

Функцията, която искате, е PDOStatement::nextRowset

Така че във вашия пример по-горе, можете да направите нещо като;

$sth = $dbh->prepare("SELECT * FROM tb1 WHERE cond1;
                      SELECT * FROM tb2 WHERE cond2");
$sth->execute();
$rowset1 = $sth->fetchAll();
$sth->nextRowset();
$rowset2 = $sth->fetchAll();

print_r($rowset1);
print_r($rowset2);

Напълно разумно е една съхранена процедура да връща повече от един набор от редове.

person Nigel Alderton    schedule 27.01.2014

$rowset[] = $sth->fetchAll(PDO::FETCH_OBJ);
WHILE($sth->nextRowset()) {
    $rowset[] = $sth->fetchAll(PDO::FETCH_OBJ);
}

Сега вашият $rowset ще бъде масив. Можете да използвате count(), за да разберете колко набора редове имате. И използвайте foreach цикъл, за да получите всеки набор от редове

person Michael Eugene Yuen    schedule 21.07.2017

В зависимост от конкретната версия на PHP, която използвате, може дори да не успеете да изпълните множество оператори на заявка/изпълнение.

Краткият отговор е, че не, не е по-добре да върнете две отделни таблици в една заявка. И двете таблици трябва да имат еднакъв брой колони. Няма да има начин да се различи резултат #1 от резултат #2 в PHP. И ако някога искате да промените някоя от таблиците, ще трябва да се уверите, че таблиците все още остават съвместими.

Може да успеете да напишете бенчмарк, който изпълнява няколко хиляди заявки, първо като две отделни, а след това една като UNION ALL (както е предложено по-горе). Съмнявам се, че ще намерите голяма разлика в производителността между двете. Ако SQL сървърът работи на същия физически сървър, самата заявка е почти мигновена и може да претърпите спад в производителността за извършване на UNION ALL. Ако е по кабела, към друг сървър в мрежата или през интернет (по каквато и да е причина), това ще компенсира ползата от комбинираната заявка.

Ако това са семантично отделни части от информация, просто не е много добра идея в дългосрочен план да свързвате двете заявки заедно. Това намирисва на "преждевременна оптимизация" и това е коренът на цялото зло, както казва Доналд Кнут.

person mattandersen    schedule 02.08.2013

                 $STH = $DBH->prepare('show create table `a`;
                            show create table `b`;
                            show create table `b`;
                        ');
                $STH->execute( );

                do {

                    $row =$STH->fetchAll(\PDO::FETCH_NUM);
                    if($row && count($row)>0){
                        $sql.=$row[0][1] . ';';
                    }
                } while ($STH->nextRowset());

Набор от множество резултати в един цикъл

person Joshy Francis    schedule 23.05.2018

За да отговоря на въпроса ви, не, не е възможно как го правите. Имате две възможности:

  1. Комбинирайте двете заявки в една
  2. Изпълнете двете заявки поотделно и комбинирайте резултатите им

Тъй като mysql заявките обикновено са скъпи, бих комбинирал заявките, ако изобщо е възможно. Във вашия случай можете да използвате просто UNION:

SELECT row1, row2, row3
FROM tb1
WHERE id < 10
UNION ALL
SELECT row1, row2, row3
FROM tb2
WHERE id < 10

Вероятно обаче трябва да прецените защо използвате две отделни таблици. Ако съдържат припокриващи се данни, може би е по-добре да се комбинират в една таблица, ако е възможно.

person Mike    schedule 02.08.2013
comment
3. Създайте разумна база данни, за да съхранявате всички подобни данни в една таблица - person Your Common Sense; 03.08.2013
comment
@YourCommonSense Не знам как изглежда структурата на таблицата му. Доколкото знам, може би id са единствените подобни данни и може да има основателна причина да го направите в две таблици. Но да, съгласен съм с теб. - person Mike; 03.08.2013
comment
@YourCommonSense Може би си прав. Веднъж проектирах система, която следи определени промени, които са направени. Различни неща могат да се променят, така че за всеки тип го съхранявам в различна таблица. Някои са промени в дати, някои са промени на атрибут от една стойност в друга, някои са добавяне/изтриване на редове. За тези, които добавят редове, не бих искал да има колона DATE, защото не се прилага, затова ги разделих. Може би трябва да преоценя как се съхранява. - person Mike; 03.08.2013
comment
@Mike Има две напълно различни таблици и с напълно различен идентификатор. - person silversky; 03.08.2013
comment
@Mike Добра идея ли е да изпълните и двете заявки поотделно и да комбинирате техните резултати? Спестявам ли време? Или използване на процесора? - person silversky; 03.08.2013
comment
Защо бихте искали да комбинирате резултати от напълно различни таблици? - person Your Common Sense; 03.08.2013
comment
@silversky може би се опитайте да развиете малко въпроса си и да ни покажете какво всъщност се опитвате да постигнете; какво държат таблиците, какво искате да направите с резултатите и т.н. - person Mike; 03.08.2013

Може би имате нужда от JOIN, ако тези таблици са свързани.
Или 2 отделни извиквания, ако това са напълно различни и неподходящи таблици.

Невъзможно е да се каже повече поради изключително краткия и неясен въпрос.

Както и да е, няма причина да комбинирате заявки само от желание да ги изпълните всички в едно пътуване.

person Your Common Sense    schedule 02.08.2013