Nota SPIP-Contrib : une contrib qui remonte initialement a août 2005 (post SPIP 1.9 donc), depuis de nombreuses choses on changé sur le code, en particulier pour le portage multibase, voir par exemple : Portage de SPIP en PostGres
Une contrib donc probablement à remanier et à aboutir, mais la preuve est déjà faite que c’est possible ... contributeurs à vos claviers
Interroger une base Oracle grâce au MultiBase
Après plusieurs heures de recherche, de debug, j’ai enfin réussi à interroger une base Oracle.
voici donc le résultat des mes investigations :
Prérequis
Une connexion à Oracle qui fonctionne,
- vérifiez que vous avez bien un client oracle installé sur votre machine
- que le fichier
TNSNAMES.ORA
est bien configuré - que l’extension php est installée
dans le fichierphp.ini
supprimer le point virgule devant extension;extension=php_oracle.dll
note : J’ai choisi de me connecter avec les commandes php Oracle ora
, et non avec les commandes Oracle 8 oci
, pas pour la simplicité du code, mais plutôt parce que je n’ai pas réussi a me connecter à ma base de tests avec les oci
.
le fichier de connection et de traitement des boucles
j’ai créé un fichier inc_connect-ora.php3 avec pour début :
if (defined("_ECRIRE_INC_CONNECT_ORA")) return;
define("_ECRIRE_INC_CONNECT_ORA", "1");
global $connexion ;
$tns = monserveur';
$user = "login@$tns";
$pass = 'pass';
$connexion = ora_logon($user, $pass);
if ($connexion == FALSE) {
echo "<h1>Erreur d'ouverture de ora_logon</h1>".ora_errorcode($connexion)." : ".ora_error($connexion) ;
}
et avec les fonctions suivantes :
function spip_ora_select, notez la gestion de $limit
différente de mysql.
function spip_ora_select($select, $from, $where, $groupby, $orderby, $limit, $sousrequete, $cpt, $table, $id, $serveur)
{
global $connexion ;
// gestion de la variable $limit
if ($limit <> ""){
$limit_ora = explode(",", $limit,2);
$start = $limit_ora['0'];
$end = $limit_ora['1'];
}
$q = " FROM " . ereg_replace (" AS ", " ",join(",", $from)) // supprimer le AS de la commande MYSQL
. ($where ? " WHERE " . join(" AND ", $where) : '')
. ($groupby ? " GROUP BY $groupby " : '')
. ($orderby ? " ORDER BY ". join(", ", $orderby) : '');
if ($limit <> ""){
$q .= " ) WHERE n BETWEEN $start AND $end"; // pour oracle
}
if (!$sousrequete)
if ($limit <> ""){
$q = "SELECT * FROM ( SELECT ROWNUM AS n, ". join(", ", $select) . $q; // gestion de la variable $limit
}else{
$q = "SELECT ROWNUM AS n, ". join(", ", $select) . $q;
}
else
$q = " SELECT S_" . join(", S_", $select)
. " FROM (" . join(", ", $select)
. ", COUNT(".$sousrequete.") compteur " . $q
.") AS S_$table WHERE compteur=" . $cpt;
// Erreur ? C'est du debug de squelette, ou une erreur du serveur
if ($GLOBALS['var_mode'] == 'debug') {
boucle_debug_resultat($id, '', $q);
}
$q = ereg_replace (strtolower($serveur)."_", "", $q);
// remplacer le debut des noms de tables pour coller avec les tables réelles du serveur
// permet de ne pas avoir un doublon avec les tables spip
$mycursor = ora_open ($connexion);
if ($mycursor == FALSE){
echo "<h1>Erreur d'ouverture de ora_open</h1>".ora_error($mycursor)."".ora_errorcode($mycursor)."<br />";
}
ora_parse ($mycursor, $q, 0);
if ($mycursor == FALSE){
echo "<h1>Erreur d'ouverture de ora_parse</h1>".ora_error($mycursor)."".ora_errorcode($mycursor)."<br />";
}
ora_exec ($mycursor);
if ($mycursor == FALSE){
echo "<h1>Erreur d'ouverture de ora_exec</h1>".ora_error($mycursor)."".ora_errorcode($mycursor)."<br />";
}
return $mycursor;
}
function spip_ora_fetch , ne pas oublier de remettre le résultat en minusucules !!!
function spip_ora_fetch($ora_cur)
{
$res = array();
ora_fetch_into($ora_cur, $res, ORA_FETCHINTO_ASSOC);
$res = array_change_key_case($res, CASE_LOWER); // pour retourner le nom des tables en minuscules
return $res;
}
function spip_ora_count
function spip_ora_count($res) {
if ($res)
return ora_numrows($res);
}
function spip_ora_free
function spip_ora_free($res) {
global $connexion;
if ($res)
if ( ora_close($res) == FALSE) {
echo "<h1>Erreur de fermeture de ora_close</h1>".ora_errorcode($connexion)." : ".ora_error($connexion) ;
}
return $res;
}
Définition des tables
dans le fichier monsquelette_fonctions.php3
$articles = array(
"article" => "VARCHAR2(40) NOT NULL",
"categorie" => "VARCHAR2(2)",
"famille" => "VARCHAR2(3)",
"sou_famille" => "VARCHAR2(5)"
);
$articles_key = array(
"PRIMARY KEY" => "article"
);
$table_ora['ora_articles'] =
array('field' => &$articles, 'key' => &$articles_key);
$ephemeres_options = array(
"soc" => "VARCHAR2(3)",
"ephemere" => "VARCHAR2(40) NOT NULL",
"opton" => "VARCHAR2(18)",
"valeur_n" => "NUMBER",
);
$ephemeres_options_key = array(
"PRIMARY KEY" => "ephemere"
);
$table_ora['ora_ephemeres_options'] =
array('field' => &$ephemeres_options, 'key' => &$ephemeres_options_key);
$GLOBALS['tables_des_serveurs_sql']['ORA']=&$table_ora;
note importante : il faut s’arranger pour que les tables définies dans le tableau $GLOBALS['tables_des_serveurs_sql']
n’aient pas le même noms que les tables de SPIP, pour cela j’ai préfixé toutes les tables de « ora_ » qui correspond au code de connexion du serveur ($table_ora['ora_articles'] =
.
la boucle dans le squelette
<BOUCLE_ART(ORA:ORA_ARTICLES){categorie = "MP"}{famille="PRO"}{par article}{0,10}>
#ARTICLE #CATEGORIE #FAMILLE #SOU_FAMILLE<br />
</BOUCLE_ART>
Allez, je complique les choses et vais réaliser un lien entre les table ARTICLES et EPHEMERE_OPTIONS
articles.article = ephemeres_options.ephemere
<BOUCLE_ART2(ORA:ORA_ARTICLES){categorie = "MP"}{famille="PRO"}{par article}{0,10}>
#ARTICLE<br />
<ol>
<BOUCLE_EPH(ORA:ORA_EPHEMERES_OPTIONS){ephemere=#ARTICLE}{par opton}>
<li>#OPTON : #VALEUR_N</li>
</BOUCLE_EPH>
Pas d'option
<//B_EPH>
</ol>
</BOUCLE_ART2>
TODO :
- Fermer proprement la connexion à la base oracle
- tester, tester, et encore tester... merci pour votre aide...
Remerciements
merci beaucoup à :
- mortimer
- Déesse A.
- Philippe Martin
pour leur aide...
N’hésitez pas a participer : ajouter vos commentaires, corrections, etc...
@+ Coyote