2009-04-29 3 views
27

Ho due domande, come segue:Come eseguire due query mysql come una in PHP/MYSQL?

SELECT SQL_CALC_FOUND_ROWS Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10; 
SELECT FOUND_ROWS(); 

voglio eseguire sia queste query in un unico tentativo.

$result = mysql_query($query); 

Ma allora dimmi come ti gestire ogni tavoli separatamente. In realtà in ASP.NET che utilizza set di dati che gestisce due query come

ds.Tables[0]; 
ds.Tables[1]; .. etc 

Come posso fare lo stesso utilizzando PHP/MYSQL?

+0

** Questo è possibile ** (consultare http://stackoverflow.com/a/28984274/632951) utilizzando il flag 'CLIENT_MULTI_STATEMENTS'. – Pacerier

risposta

32

Aggiornamento: A quanto pare possibile passando una bandiera per mysql_connect(). Vedere Executing multiple SQL queries in one statement with PHP Tuttavia, qualsiasi lettore corrente dovrebbe evitare di utilizzare la classe mysql_ e preferire PDO.

Non si può fare che utilizzando il normale mysql-api in PHP. Basta eseguire due query. Il secondo sarà così veloce che non avrà importanza. Questo è un tipico esempio di micro ottimizzazione. Non preoccuparti per questo

Per la cronaca, si può essere fatto utilizzando mysqli e il mysqli_multi_query -funzione.

+3

Sono fondamentalmente preoccupato per le prestazioni, che penso diminuiranno se colpiremo il database due volte. – Prashant

+1

Fai un punto di riferimento se non sei convinto. Il tempo necessario per eseguire la query SELECT FOUND_ROWS() e recuperare il risultato è trascurabile. Hai già la connessione e il set di risultati è estremamente piccolo (solo un intero). –

+8

BTW, se sei preoccupato per le prestazioni dovresti passare il tempo a cercare di sbarazzarti dell'istruzione LIKE '% prashant%'. Questo è probabilmente un vero problema di prestazioni. Come regola generale: il collo di bottiglia per la maggior parte delle applicazioni php non è in PHP, ma piuttosto nel database. Se vuoi dedicare del tempo a ottimizzare la tua applicazione, spenderla rivedendo i tuoi indici e SPIEGARE le tue domande. –

2

Ti piace questa:

$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); 
+0

Non voleva evitare di eseguire mysql_query due volte? –

+0

Sì, voglio evitare le queries di mysql due volte. E nella risposta @ Jon Benedicto, sta eseguendo due domande. :( – Prashant

+0

Ho appena postato un'altra risposta che mostra come eseguire entrambe le query in una volta sola usando MySQLi –

0

Si dice sul sito PHP che multiple queries are NOT permitted (EDIT: Questo è vero solo per il mysql estensione mysqli e PDO consentire le query multiple.) . Quindi non puoi farlo in PHP, MA, perché non puoi semplicemente eseguire quella query in un'altra chiamata mysql_query, (come nell'esempio di Jon)? Dovrebbe comunque darti il ​​risultato corretto se usi la stessa connessione. Inoltre, mysql_num_rows può anche aiutare.

+0

Questo vale solo per l'estensione mysql mysqli e PDO consentono più query –

3

Usando SQL_CALC_FOUND_ROWS non si può.

Il numero di righe disponibile tramite FOUND_ROWS() è temporaneo e non è destinato a essere disponibile dopo l'istruzione che segue l'istruzione SELECT SQL_CALC_FOUND_ROWS.

Come qualcuno ha notato nella domanda precedente, l'utilizzo di SQL_CALC_FOUND_ROWS è spesso più lento di un semplice conteggio.

Forse si sarebbe migliore fuori a fare questo come come subquery:

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; 
+0

SQL_CALC_FOUND_ROWS è più lento, ma all'indirizzo http: //dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows link Ho trovato "Tuttavia, questo è più veloce di eseguire nuovamente la query senza LIMIT, perché non è necessario inviare il set di risultati al client. " – Prashant

+1

Ma non in questo caso, poiché la query non può utilizzare indici. SQL_CALC_FOUND_ROWS risulterà in una scansione di una singola tabella, mentre la sottoquery risulterà in due, e quindi è molto più lenta. hai dimenticato una virgola dopo total_rows –

+1

Sì, beh, non stai eseguendo nuovamente la query senza limite. Stai eseguendo un conteggio (*), che invia una riga. Davvero, Emil H ha un buon punto: è una micro ottimizzazione di du valore bile. Esegui due query, o se devi assolutamente farlo, fallo come subquery come ti ho spiegato. (Emil H, grazie per aver indicato la virgola mancante.) – tpdi

3

Dovrete utilizzare l'estensione MySQLi se non si desidera eseguire una query due volte:

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); 
} 
2

Devi usare MySQLi, sotto il codice funziona bene

<?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(); 
?> 
7

Come altri hanno risposto, l'API mysqli può eseguire più query con la funzione msyqli_multi_query().

Per quel che vale, DOP supporta multi-query per impostazione predefinita, e si possono scorrere i più set di risultati dei vostri più query:

$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()); 

Tuttavia, multi-query è abbastanza ampiamente considerato un cattivo idea per motivi di sicurezza. Se non si presta attenzione a come si costruiscono le stringhe di query, è possibile ottenere il tipo esatto di vulnerabilità di SQL injection mostrato nello classic "Little Bobby Tables" XKCD cartoon. Quando si utilizza un'API che ti limita a una singola query, ciò non può accadere.

0

Sì, è possibile senza utilizzare l'estensione MySQLi.

Utilizzare semplicemente CLIENT_MULTI_STATEMENTS nel 5 ° argomento di mysql_connect.

Fare riferimento ai commenti sotto Husni's post per ulteriori informazioni.