Мое решение может не сработать для вас, но это сработало для меня. (Нет, это не пуленепробиваемый либо, но делает работу для моего конкретного приложения).

огда не использовал mysqli_multi_query раньше, и это поражает мой мозг, любые примеры, которые я нахожу в сети, не помогают мне точно определить, что именно я хочу сделать.

Вот мой код:

<?php

    $link = mysqli_connect("server", "user", "pass", "db");

    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }

    $agentsquery = "CREATE TEMPORARY TABLE LeaderBoard (
        `agent_name` varchar(20) NOT NULL,
        `job_number` int(5) NOT NULL,
        `job_value` decimal(3,1) NOT NULL,
        `points_value` decimal(8,2) NOT NULL
    );";
    $agentsquery .= "INSERT INTO LeaderBoard (`agent_name`, `job_number`, `job_value`, `points_value`) SELECT agent_name, job_number, job_value, points_value FROM jobs WHERE YEAR(booked_date) = $current_year && WEEKOFYEAR(booked_date) = $weeknum;";
    $agentsquery .= "INSERT INTO LeaderBoard (`agent_name`) SELECT DISTINCT agent_name FROM apps WHERE YEAR(booked_date) = $current_year && WEEKOFYEAR(booked_date) = $weeknum;";
    $agentsquery .= "SELECT agent_name, SUM(job_value), SUM(points_value) FROM leaderboard GROUP BY agent_name ORDER BY SUM(points_value) DESC";

    $i = 0;
    $agentsresult = mysqli_multi_query($link, $agentsquery);

    while ($row = mysqli_fetch_array($agentsresult)){
        $number_of_apps = getAgentAppsWeek($row['agent_name'],$weeknum,$current_year);
        $i++;
?>

            <tr class="tr<?php echo ($i & 1) ?>">
                <td style="font-weight: bold;"><?php echo $row['agent_name'] ?></td>
                <td><?php echo $row['SUM(job_value)'] ?></td>
                <td><?php echo $row['SUM(points_value)'] ?></td>
                <td><?php echo $number_of_apps; ?></td>
            </tr>

<?php

    }
?>

Все, что я пытаюсь сделать, это запустить несколько запросов, а затем использовать окончательные результаты этих четырех запросов и поместить их в мои таблицы.

код выше действительно не работает вообще, я просто получаю следующую ошибку:

Предупреждение: mysqli_fetch_array () ожидает, что параметр 1 будет mysqli_result, логическое значение задано в C: \ xampp \ htdocs \ hydroboard \ hydro_reporting_2010.php в строке 391

любая помощь?

Ответы на вопрос(6)

что вы пытаетесь сделать, создав хранимую процедуру, которая будет генерировать статистику лидера / агента, а затем просто вызывать ее из вашего php (одиночного вызова) следующим образом:

полный сценарий здесь:http://pastie.org/1451802

в качестве альтернативы, вы могли бы, вероятно, объединить ваши отдельные запросы в один оператор select / group by.

глянь сюда :http://pastie.org/1451842

select
 leaders.agent_name, 
 sum(leaders.job_value) as sum_job_value, 
 sum(leaders.points_value) as sum_points_value 
from
(
select 
 agent_name, 
 job_number, 
 job_value, 
 points_value 
from 
 jobs 
where 
 year(booked_date) = 2011 and weekofyear(booked_date) = 2
union all
select distinct
 agent_name,
 0,0,0
from
 apps
where 
 year(booked_date) = 2011 and weekofyear(booked_date) = 2
) leaders
group by
 agent_name 
order by sum_points_value desc;
Хранимая процедура
drop procedure if exists list_leaders;

delimiter #
create procedure list_leaders
(
in p_year smallint unsigned,
in p_week tinyint unsigned
)
begin

  create temporary table tmp_leaders(
    agent_name varchar(20) not null,
    job_number int unsigned not null default 0, -- note the default values
    job_value decimal(3,1) not null default 0,
    points_value decimal(8,2) not null default 0
  )engine=memory;

  insert into tmp_leaders (agent_name, job_number, job_value, points_value) 
    select agent_name, job_number, job_value, points_value from jobs 
    where year(booked_date) = p_year and weekofyear(booked_date) = p_week;

  insert into tmp_leaders (agent_name) -- requires default values otherwise you will get nulls
    select distinct agent_name from apps
    where year(booked_date) = p_year and weekofyear(booked_date) = p_week;

  select 
    agent_name, 
    sum(job_value) as sum_job_value, 
    sum(points_value) as sum_points_value 
   from
    tmp_leaders
   group by
    agent_name order by sum_points_value desc;

  drop temporary table if exists tmp_leaders;

end#

delimiter ;

call list_leaders(year(curdate()), weekofyear(curdate()));
PHP скрипт
<?php

ob_start(); 

try
{
    $db = new mysqli("localhost", "foo_dbo", "pass", "foo_db", 3306);

    if ($db->connect_errno) 
        throw new exception(sprintf("Could not connect: %s", $db->connect_error));

    $sqlCmd = "call list_leaders(2011, 2)";
    $result = $db->query($sqlCmd);

    if(!$result) throw new exception(sprintf("Invalid query : %s", $sqlCmd));

    if($db->affected_rows <= 0){
        echo "no leaders found !";
    }
    else{
        $leaders = $result->fetch_all(MYSQLI_ASSOC);
        foreach($leaders as $ldr){
            // do stuff
            echo $ldr["agent_name"], "<br/>";
        }
    }
}
catch(exception $ex)
{
    ob_clean(); 
    echo sprintf("zomg borked - %s", $ex->getMessage());
}

if(!$db->connect_errno) $db->close();
ob_end_flush();
?>

Как-то проще сейчас - надеюсь, это поможет :)

 Harry Weinert12 янв. 2011 г., 11:59
Спасибо за помощь f00, но я не думаю, что я вполне готов к объектно-ориентированному php-скрипту; D, это совершенно ошеломляет меня. - однако я исправил свою проблему! Я выложу ответ :)
 Jon Black12 янв. 2011 г., 12:03
Вы можете сделать все это в одном запросе - посмотрите мое альтернативное решениеpastie.org/1451842

руководство по эксплуатации: mysqli_multi_query() возвращаетbool указывая на успех.

Чтобы получить набор результатов из первого запроса, вы можете использовать mysqli_use_result () или mysqli_store_result (). Все последующие результаты запроса могут быть обработаны с помощью mysqli_more_results () и mysqli_next_result ().

Вот функция, которая возвращает последний результат мультизапроса:

function mysqli_last_result($link) {
    while (mysqli_more_results($link)) {
        mysqli_use_result($link); 
        mysqli_next_result($link);
    }
    return mysqli_store_result($link);
}

Использование:

$link = mysqli_connect();

$query  = "SELECT 1;";
$query .= "SELECT 2;";
$query .= "SELECT 3";

mysqli_multi_query($link, $query);
$result = mysqli_last_result($link);
$row = $result->fetch_row();
echo $row[0];  // prints "3"

$result->free();
mysqli_close($link);
 tim08 февр. 2013 г., 03:48
пример кода php.net:php.net/manual/en/mysqli.multi-query.php
 Harry Weinert12 янв. 2011 г., 11:33
Привет, я читал об этих командах, но я не могу понять, как использовать их в своем коде. - Я хочу использовать только результат последнего запроса, запрос SELECT ... Я не хочу использовать результаты первых 3 запросов CREATE и INSERT, поскольку они бесполезны для меня. - из того, что я читаю, эти команды use_result и т. д. извлекают результаты из каждого запроса, так как я могу игнорировать все результаты и использовать только конечный результат из запроса select ??

я тоже брошу свою шляпу на ринг в этом вопросе (и эй, это все еще процедурно и весь этот джаз). Это не доказательство глупости, но я боролся и боролся с MySQLi, и это группа веселых людей, связанных с multi_query, и я не мог заставить его играть так, как я хотел, или обладать необходимой гибкостью. Я видел несколько примеров, когда некоторые программисты просто запускалиexplode(';', $sql_statements) что заставило мои глаза кровоточить от того, насколько ужасно это может быть неправильно.

Мое решение может не сработать для вас, но это сработало для меня. (Нет, это не пуленепробиваемый либо, но делает работу для моего конкретного приложения).

<?php
    $file = file_get_contents('test_multiple_queries.sql');
    $result = preg_split("/;(?=\s*(create|insert|update|alter|show|explain|truncate|drop|delete|replace|start|lock|commit|rollback|set|begin|declare|rename|load|begin|describe|help))/im", $file);
    $result = array_map('trim', $result);

    foreach($result as $sql_query) {

        // Procedural style
        $my_query = mysqli_query($link, $sql_query);

        // Now you can get errors easily, or affected_rows, or whatever
        //    using much simpler, readable code
        mysqli_error($link);
        mysqli_affected_rows($link);

        // or go crazy with some other stuff
        $words = preg_split("/\s+/", $sql_query);
        switch(strtolower($words[0])) {
            case 'insert':
                // do something nifty like...
                echo 'New ID: '.mysqli_insert_id($link)."\n";
                break;
            case 'drop':
                // obviously run this before the query, simply here for example
                echo 'Hey young (man|lady)! We don\'t drop anything!';
                break;
            case 'select':
                // hooray for selecting stuff
                while($rs = mysqli_fetch_assoc($my_query)) {
                    // have fun with data
                }
                break;
        }
    }
Решение Вопроса

после некоторой возни, проб и ошибок и ссылки на другой пост, с которым я столкнулся в поиске Google, мне удалось решить мою проблему!

Вот новый код:

<?php

    $link = mysqli_connect("server", "user", "pass", "db");

    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }

    $agentsquery = "CREATE TEMPORARY TABLE LeaderBoard (
        `agent_name` varchar(20) NOT NULL,
        `job_number` int(5) NOT NULL,
        `job_value` decimal(3,1) NOT NULL,
        `points_value` decimal(8,2) NOT NULL
    );";
    $agentsquery .= "INSERT INTO LeaderBoard (`agent_name`, `job_number`, `job_value`, `points_value`) SELECT agent_name, job_number, job_value, points_value FROM jobs WHERE YEAR(booked_date) = $current_year && WEEKOFYEAR(booked_date) = $weeknum;";
    $agentsquery .= "INSERT INTO LeaderBoard (`agent_name`) SELECT DISTINCT agent_name FROM apps WHERE YEAR(booked_date) = $current_year && WEEKOFYEAR(booked_date) = $weeknum;";
    $agentsquery .= "SELECT agent_name, SUM(job_value), SUM(points_value) FROM leaderboard GROUP BY agent_name ORDER BY SUM(points_value) DESC";

    mysqli_multi_query($link, $agentsquery) or die("MySQL Error: " . mysqli_error($link) . "<hr>\nQuery: $agentsquery");
    mysqli_next_result($link);
    mysqli_next_result($link);
    mysqli_next_result($link);

    if ($result = mysqli_store_result($link)) {
        $i = 0;
        while ($row = mysqli_fetch_array($result)){
            $number_of_apps = getAgentAppsWeek($row['agent_name'],$weeknum,$current_year);
            $i++;
?>

            <tr class="tr<?php echo ($i & 1) ?>">
                <td style="font-weight: bold;"><?php echo $row['agent_name'] ?></td>
                <td><?php echo $row['SUM(job_value)'] ?></td>
                <td><?php echo $row['SUM(points_value)'] ?></td>
                <td><?php echo $number_of_apps; ?></td>
            </tr>

<?php

        }
    }
?>

после вставки mysqli_next_result туда несколько раз для каждого запроса он волшебным образом работал! ура! Я понимаю, почему это работает, потому что я говорю, чтобы он переходил к следующему результату 3 раза, поэтому он переходит к результату для запроса № 4, который я хочу использовать.

Хотя мне это кажется немного неуклюжим, просто должна быть команда для чего-то вроде mysqli_last_result ($ link) или чего-то еще, если вы спросите меня ...

Спасибо за помощь rik и f00, я в итоге добрался :)

 rik12 янв. 2011 г., 18:50
Я добавил функциюmysqli_last_result на мой ответ.

а, чтобы привести его в соответствие с тем, что я считаю лучшей практикой.

Хотя несколько строк mysqli_next_result ($ link) дают ожидаемый результат, это выглядит немного хакерским. Так что я собираюсь создать DO-WHILE на их месте.Решение Рика, включающее создание функции mysqli_last_result ($ link), является излишним. Мое состояние WHILE достигнет того же эффекта. Кроме того, код rik смешивает процедурные и объектно-ориентированные стили, которых следует избегать.Я не буду прыгать между PHP и HTML.Я просто немного подправлю класс.Я помещу getAgentAppsWeek () прямо в строку, поскольку я не люблю создавать переменные, которые упоминаются только один раз; и потому, что Гарри Вейнерт проделал хорошую работу по названию функции.

ИМО это просто легче читать.

if(mysqli_multi_query($link,$agentsquery)){
    do{
        if($result=mysqli_store_result($link)){ // ignore if no record set
            while($row=mysqli_fetch_array($result)){
                echo "<tr class=\"tr",(++$i & 1),"\">";
                    echo "<td style=\"font-weight:bold;\">",$row['agent_name'],"</td>";
                    echo "<td>",$row['SUM(job_value)'],"</td>";
                    echo "<td>",$row['SUM(points_value)'],"</td>";
                    echo "<td>",getAgentAppsWeek($row['agent_name'],$weeknum,$current_year),"</td>";
                echo "</tr>";
            }
            mysqli_free_result($result);
        }
    } while(mysqli_more_results($link) && mysqli_next_result($link));
}
if($error_mess=mysqli_error($link)){
    echo "<tr class=\"error\"><td colspan=\"4\">Error: $error_mess</td></tr>";
}
//if any query returns false, mysqli_multi_query will stop
// and the individual query error to blame will be provided.

в конце концов, используйте эту переменную.

    do{
        if($result = $con->store_result()){
            $data=$result->fetch_all();
            $result->free();
        }
    } while($con->more_results()&&$con->next_result());
    echo(json_encode($data));

Ваш ответ на вопрос