Может ли 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 Есть две совершенно разные таблицы и с совершенно разными id. - 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