Pendant le processus de développement à l'aide de CodeIgniter (en particulier Codeigniter 3), nous devons parfois exécuter des blocs d'instructions (multi-remery) contenant plusieurs requêtes SQL. Par exemple, nous pourrions vouloir appeler plusieurs procédures stockées à la fois, ou exécuter plusieurs requêtes dans une demande d'amélioration de l'efficacité.
Cependant, lors de l'utilisation de la requête multi-statement, un problème courant est: seul le premier ensemble de résultats est accessible et d'autres ensembles de résultats ne peuvent pas être obtenus . En effet, Codeigniter ne traite pas automatiquement plusieurs ensembles de résultats lors de l'utilisation des pilotes MySQLI. Pour résoudre ce problème, nous devons appeler manuellement la méthode $ this-> db-> next_result () pour nettoyer l'ensemble de résultats précédent et préparer le système pour le suivant.
Cet article vous montrera comment utiliser correctement Next_Result () dans CodeIigniter pour gérer les requêtes multi-déclarations.
Supposons que vous ayez un fichier de procédure stocké ou exécutez SQL comme ce qui suit directement dans le contrôleur:
$sql = "
CALL get_users();
CALL get_orders();
";
Pour exécuter ce type de SQL multi-statement, vous pouvez utiliser la méthode Query () et gérer manuellement le jeu de résultats:
$result = $this->db->query("CALL get_users();");
if ($result) {
$users = $result->result();
// Nettoyez le premier ensemble de résultats
$result->free_result();
$this->db->next_result();
// Obtenez le deuxième ensemble de résultats
$result2 = $this->db->query("CALL get_orders();");
if ($result2) {
$orders = $result2->result();
// Nettoyer à nouveau
$result2->free_result();
$this->db->next_result();
}
}
Cette méthode convient pour appeler une seule procédure stockée à la fois, puis exécuter manuellement l'instruction suivante. Mais si vous souhaitez exécuter plusieurs instructions SQL à la fois, par exemple:
$sql = "
CALL get_users();
CALL get_orders();
CALL get_products();
";
Il peut être mis en œuvre à l'aide de la fonction multi_query () native de Mysqli.
Dans CodeIgniter, si vous utilisez le pilote MySQLI, vous pouvez le faire:
$mysqli = $this->db->conn_id; // Obtenez le sous-jacent MySQLi Connectez-vous aux ressources
$sql = "
CALL get_users();
CALL get_orders();
CALL get_products();
";
if ($mysqli->multi_query($sql)) {
do {
if ($result = $mysqli->store_result()) {
// Traiter l'ensemble de résultats actuel
$data[] = $result->fetch_all(MYSQLI_ASSOC);
$result->free();
}
} while ($mysqli->more_results() && $mysqli->next_result());
}
Ce code va récupérer plusieurs ensembles de résultats à son tour et utiliser Next_Result () pour préparer le suivant.
Bien que vous puissiez utiliser directement Multi_Query () , il est fortement recommandé d'exécuter plusieurs instructions séparément , surtout si vous avez des exigences élevées pour la sécurité et la stabilité. Pour les opérations de base de données, les pratiques suivantes sont recommandées:
Appelez Free_Result () et Next_Result () après chaque requête pour nettoyer la connexion.
Évitez d'écrire plusieurs appels directement dans le modèle, mais les encapsules en un seul appel, et un contrôle logique est placé dans la couche PHP.
Si vous devez utiliser Multi_Query () , assurez-vous de traiter tous les ensembles de résultats renvoyés et d'éviter l'erreur "Commandes hors synchronisation".
Vous pouvez encapsuler ce processus dans une méthode de modèle et renvoyer un tableau contenant plusieurs ensembles de données:
public function get_multi_data()
{
$mysqli = $this->db->conn_id;
$sql = "
CALL get_users();
CALL get_orders();
CALL get_products();
";
$data = [];
if ($mysqli->multi_query($sql)) {
do {
if ($result = $mysqli->store_result()) {
$data[] = $result->fetch_all(MYSQLI_ASSOC);
$result->free();
}
} while ($mysqli->more_results() && $mysqli->next_result());
}
return $data;
}
Dans le contrôleur, vous pouvez l'appeler comme ceci:
$this->load->model('Data_model');
$result_sets = $this->Data_model->get_multi_data();
$users = $result_sets[0];
$orders = $result_sets[1];
$products = $result_sets[2];
Lors du débogage de la requête multi-statement, il est recommandé d'activer la fonction de journalisation de CodeIgniter et d'observer le contenu dans les applications / journaux pour faciliter les erreurs de dépannage.