Como executar duas consultas mysql como um em PHP / MySQL?
Pergunta
Eu tenho duas consultas, como a seguir:
SELECT SQL_CALC_FOUND_ROWS Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
SELECT FOUND_ROWS();
eu quero executar essas duas consultas em uma única tentativa.
$result = mysql_query($query);
Mas então me dizer como eu vou lidar com cada mesas separadamente. Na verdade, no ASP.NET que usa conjunto de dados que lida com duas consultas como
ds.Tables[0];
ds.Tables[1]; .. etc
Como posso fazer o mesmo usando PHP / MySQL?
Solução
Update: Aparentemente possível passando um sinalizador para mysql_connect()
. Consulte Executar várias consultas SQL em uma instrução com PHP no entanto, qualquer leitor atual deve evitar o uso do mysql_
-classe de funções e preferem PDO.
Você não pode fazer isso usando o mysql-api regular em PHP. Basta executar duas consultas. O segundo será tão rápido que ele não importa. Este é um exemplo típico de micro otimização. Não se preocupe com isso.
Para o registro, isso pode ser feito usando mysqli eo mysqli_multi_query -função.
Outras dicas
Como já foi atendida, a API mysqli pode executar multi-consultas com a função msyqli_multi_query ().
Por que vale a pena, DOP suporta multi-consulta por padrão, e você pode iterar sobre os vários conjuntos de resultados de suas várias consultas:
$stmt = $dbh->prepare("
select sql_calc_found_rows * from foo limit 1 ;
select found_rows()");
$stmt->execute();
do {
while ($row = $stmt->fetch()) {
print_r($row);
}
} while ($stmt->nextRowset());
No entanto, multi-consulta é muito amplamente considerado um má idéia por razões de segurança. Se você não for cuidadoso sobre como você construir suas seqüências de consulta, você pode realmente obter o tipo exato de vulnerabilidade de injeção SQL mostrado na clássicas "Tabelas Pouco Bobby" desenhos animados XKCD . Ao usar uma API que restringi-lo a-consulta única, que não pode acontecer.
Usando SQL_CALC_FOUND_ROWS
você não pode.
A contagem de linha disponível através FOUND_ROWS () é transitória e não se destina a estar disponível após a instrução após a instrução SELECT SQL_CALC_FOUND_ROWS.
Como alguém observou na sua pergunta anterior, usando SQL_CALC_FOUND_ROWS
é frequentemente mais lento do que apenas começando uma contagem.
Talvez você seria melhor fora de fazer isso como como subconsulta:
SELECT
(select count(*) from my_table WHERE Name LIKE '%prashant%')
as total_rows,
Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
Você vai ter que usar a extensão MySQLi se você não quiser executar uma consulta duas vezes:
if (mysqli_multi_query($link, $query))
{
$result1 = mysqli_store_result($link);
$result2 = null;
if (mysqli_more_results($link))
{
mysqli_next_result($link);
$result2 = mysqli_store_result($link);
}
// do something with both result sets.
if ($result1)
mysqli_free_result($result1);
if ($result2)
mysqli_free_result($result2);
}
Você tem que usar MySQLi, o código abaixo funciona bem
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";
/* execute multi query */
if ($mysqli->multi_query($query)) {
do {
/* store first result set */
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_row()) {
printf("%s\n", $row[0]);
}
$result->free();
}
/* print divider */
if ($mysqli->more_results()) {
printf("-----------------\n");
}
} while ($mysqli->next_result());
}
/* close connection */
$mysqli->close();
?>
Como esta:
$result1 = mysql_query($query1);
$result2 = mysql_query($query2);
// do something with the 2 result sets...
if ($result1)
mysql_free_result($result1);
if ($result2)
mysql_free_result($result2);
Ele diz no site PHP que várias consultas não são permitidos (EDIT:. Isso só é verdade para a extensão mysql mysqli e DOP permitem várias consultas) . Então você não pode fazê-lo em PHP, mas, por que você não pode simplesmente executar essa consulta em outra chamada mysql_query, (como o exemplo de Jon)? Ele ainda deve dar-lhe o resultado correto se você usar a mesma conexão. Além disso, mysql_num_rows pode ajudar também.
Sim, é possível sem usar extensão MySQLi.
Basta usar CLIENT_MULTI_STATEMENTS
na 5ª argumento de mysql_connect
.
Consulte os comentários abaixo de Husni pós para obter mais informações.