Bonsoir,
merci de ta réponse, ci-dessous, le code du script "Class_HBL_Connecteur_BD_PDO.inc.php" qui est importé par le script encore plus bas :
<?php
include_once( 'Constants.inc.php' );
class HBL_Connecteur_BD extends PDO {
/**
* Cette classe gère les connexions à la base de données tout en offrant une couche d'abastraction.
* Effectivement, seule cette classe connait la localisation du fichier de paramètre externe.
*/
public $LastInsertId; // Dernier ID créé
public $RowCount; // Nombre d'occurrences modifiées
public function __construct() {
/**
* Connexion à la base de données via le constructeur de PDO.
*
* @return Renvoi "true" en cas de succès de connexion à la base de données, sinon lève une exception.
*/
// Charge les différentes variables utiles à la connexion à la base de données.
include( HBL_CONFIG_BD );
$DSN = $_Driver . ':host=' . $_Host . ';port=' . $_Port . ';dbname=' . $_Base ;
PDO::__construct( $DSN, $_User, $_Password, array( PDO::ATTR_PERSISTENT => TRUE ) );
return TRUE;
}
protected $transactionBegin = FALSE;
public function begin_Transaction() {
/**
* Mise en place d'une Transaction (permettant l'exécution de plusieurs requêtes SQL et de valider cet ensemble)
*
* @return Passe l'objet en mode Transaction
*/
//$this->transactionBegin = TRUE;
$this->transactionBegin = TRUE;
//$this->exec( 'BEGIN' );
return $this->beginTransaction();
}
public function commit_Transaction(){
/**
* Valide l'ensemble des requêtes de mise à jour de la Transaction.
*
* @return Passe l'objet en mode "autocommit" à "off"
*/
if ( ! $this->transactionBegin ) return;
$this->transactionBegin = FALSE;
return $this->commit();
}
public function rollback_Transaction(){
/**
* Annule l'ensemble des requêtes de mise à jour de la Transaction.
*
* @return Conserve l'objet en mode Transaction
*/
if ( ! $this->transactionBegin ) return;
$this->transactionBegin = FALSE;
//$this->exec( 'ROLLBACK' );
return $this->rollBack();
}
public function prepareSQL( $sql ) {
/**
* Automatise la préparation d'une requète en ajoutant la gestion des exceptions
*
* @param[in] $sql La requête à préparer
*
* @return Renvoi la requête préparée
*/
// évite les espaces insécables dans la chaîne de caractère :s
$sql = str_replace(" ", " ", $sql);
if ( ! $Query = $this->prepare( $sql ) ) {//print('Error : '.$sql);
$Error = $Query->errorInfo();
if ( $this->transactionBegin == TRUE ) $this->rollback_Transaction();
throw new Exception( $Error[ 2 ], $Error[ 1 ] );
}
return $Query;
}
public function bindSQL( $Query, $Reference, $Value, $Type, $Length = 10 ){
/**
* Automatise l'association des paramètres sur une requète SQL.
*
* @param[in] $Query La requète modifier, passé en référence
* @param[in] $Reference la chaine de caractère référence à remplacer dans la requête
* @param[in] $Value la valeur à mettre à la place de la référence
* @param[in] $Type le type de variable à remplacer. Pour l'instant ne sont géré que les entiers et les chaines de caractères
* @param[in] $Length la longueur maximal de la chaine de caractère à remplacer
*
*/
// Si le type est un "Numérique".
if( $Type === PDO::PARAM_INT || $Type === PDO::PARAM_BOOL || $Type === PDO::PARAM_LOB ) {
if ( ! $Query->bindParam( $Reference, $Value, $Type ) ) {
$Error = $Query->errorInfo();
if ( $this->transactionBegin == TRUE ) $this->rollback_Transaction();
throw new Exception( $Error[ 2 ], $Error[ 1 ] );
}
}
// Si le type est une "chaine de caractères".
elseif($Type === PDO::PARAM_STR){
if ( ! $Query->bindParam( $Reference, $Value, $Type, $Length ) ) {
$Error = $Query->errorInfo();
if ( $this->transactionBegin == TRUE ) $this->rollback_Transaction();
throw new Exception( $Error[ 2 ], $Error[ 1 ] );
}
}
else {
if ( $this->transactionBegin == TRUE ) $this->rollback_Transaction();
throw new Exception( "bindSQL - Format de donnée non géré");
}
// permet les appels en cascade
return $this;
}
public function executeSQL( $Query ){
/**
* Automatise l'exécution d'une requête
*
* @param[in] $Query La requète à executer, passé en référence
*
*/
$Status = $Query->execute();
if ( $Status === FALSE ) {
$Error = $Query->errorInfo();
var_dump($Error);
if ( $Error[ 0 ] == 23505 ) { // Gestion des doublons.
//throw new Exception("Application Error (".$Error[0].', '.$Error[2].')', $Error[ 0 ]);
throw new Exception("Application Error", $Error[ 0 ]);
}
if ( $this->transactionBegin == TRUE ) $this->rollback_Transaction();
$message = $Error[ 2 ] . ' (SQL: ' . $Error[ 0 ] . ')'; //(' . $Query->queryString . ')';
throw new Exception( $message, $Error[ 1 ] );
}
$this->LastInsertId = $this->lastInsertId();
$this->RowCount = $Query->rowCount();
// permet les appels en cascade
return $Query;
}
}
Et voici le script d'exemple appelant :
<?php
include( 'Librairies/Class_HBL_Connecteur_BD_PDO.inc.php' );
const CODE_TYPE = PDO::PARAM_STR;
const CODE_LENGTH = 10;
const LANGUE_TYPE = PDO::PARAM_STR;
const LANGUE_LENGTH = 2;
const LIBELLE_TYPE = PDO::PARAM_STR;
const LIBELLE_LENGTH = 20;
$cnxBD = new HBL_Connecteur_BD();
$cnxBD->begin_Transaction();
print('BEGIN<br>');
$SQL = 'SELECT COUNT(lbr_code) AS "total" FROM lbr_libelles_referentiel ' .
'WHERE lbr_code = :code ' .
'AND lng_id = :langue ';
print($SQL.'<br>');
$Requete = $cnxBD->prepareSQL( $SQL );
$cnxBD->bindSQL( $Requete, ':code', 'XXX_XX', CODE_TYPE, CODE_LENGTH )
->bindSQL( $Requete, ':langue', 'fr', LANGUE_TYPE, LANGUE_LENGTH );
$cnxBD->executeSQL( $Requete );
$Resultat = $Requete->fetch( PDO::FETCH_OBJ )->total;
print($Resultat.'<br>');
$SQL = 'SELECT COUNT(lbr_code) AS "total" FROM lbr_libelles_referentiel ' .
'WHERE lbr_code = :code ' .
'AND lng_id = :langue ';
print($SQL.'<br>');
$Requete = $cnxBD->prepareSQL( $SQL );
$cnxBD->bindSQL( $Requete, ':code', 'XXX_XX', CODE_TYPE, CODE_LENGTH )
->bindSQL( $Requete, ':langue', 'fr', LANGUE_TYPE, LANGUE_LENGTH );
$cnxBD->executeSQL( $Requete );
$Resultat = $Requete->fetch( PDO::FETCH_OBJ )->total;
print($Resultat.'<br>');
if ( $Resultat > 0 ) {
$SQL = 'DELETE FROM lbr_libelles_referentiel ' .
'WHERE lbr_code = :code ' .
'AND lng_id = :langue ';
print($SQL.'<br>');
$Requete = $cnxBD->prepareSQL( $SQL );
$cnxBD->bindSQL( $Requete, ':code', 'XXX_XX', CODE_TYPE, CODE_LENGTH );
$cnxBD->bindSQL( $Requete, ':langue', 'fr', LANGUE_TYPE, LANGUE_LENGTH );
$cnxBD->executeSQL($Requete);
}
$Requete = $cnxBD->prepareSQL(
'INSERT INTO lbr_libelles_referentiel '.
'(lbr_code, lng_id, lbr_libelle) ' .
'VALUES ' .
'(:Code, :Langue, :Libelle)'
);
print($SQL.'<br>');
$cnxBD->bindSQL($Requete, ':Code', 'YYYY_YY', CODE_TYPE, CODE_LENGTH);
$cnxBD->bindSQL($Requete, ':Langue', 'fr', LANGUE_TYPE, LANGUE_LENGTH);
$cnxBD->bindSQL($Requete, ':Libelle', 'xxxxxxxxxxxxxx', LIBELLE_TYPE, LIBELLE_LENGTH);
$cnxBD->executeSQL($Requete);
$cnxBD->commit_Transaction();
print('COMMIT<br>');
?>
J'obtiens l'erreur ci-dessous (erreur + résultats des "print") :
Code : Tout sélectionner
BEGIN
SELECT COUNT(lbr_code) AS "total" FROM lbr_libelles_referentiel WHERE lbr_code = :code AND lng_id = :langue
1
SELECT COUNT(lbr_code) AS "total" FROM lbr_libelles_referentiel WHERE lbr_code = :code AND lng_id = :langue
array(3) { [0]=> string(5) "25P02" [1]=> int(7) [2]=> string(87) "ERROR: current transaction is aborted, commands ignored until end of transaction block" }
Fatal error: Uncaught Exception: ERROR: current transaction is aborted, commands ignored until end of transaction block (SQL: 25P02) in /Applications/XAMPP/xamppfiles/htdocs/Loxense_v1/Librairies/Class_HBL_Connecteur_BD_PDO.inc.php:200 Stack trace: #0 /Applications/XAMPP/xamppfiles/htdocs/Loxense_v1/PHPTest.php(45): HBL_Connecteur_BD->executeSQL(Object(PDOStatement)) #1 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/Loxense_v1/Librairies/Class_HBL_Connecteur_BD_PDO.inc.php on line 200
On note que l'erreur est simplement le deuxième "SELECT", cela ne plante même pas sur une mise à jour.