PHP-Oracle-Datenbank-Funktionsbibliothek

WBOY
Freigeben: 2016-08-08 09:33:46
Original
857 Leute haben es durchsucht

Klasse DB_Sql {
var $Debug = false;
var $Home = "/u01/app/Oracle/PRoduct/8.0.4";
var $Remote = 1;
/* Diese Abfrage wird direkt nach der ersten Verbindung gesendet
Beispiel:
var $ConnectQuery="ALTER session SET nls_date_lingual=german nls_date_format='DD.MM.RRRR'";
-> Legen Sie das Datumsformat für diese Sitzung fest. Dies ist in Ordnung, wenn Ihre Ora-Rolle
ist kann nicht geändert werden */
var $ConnectQuery='';
/* Aufgrund eines seltsamen Fehlers mit Oracle 8.0.5, Apache und php3.0.6
Sie müssen die ENV nicht festlegen – auf meinem System Apache
wird sich in einen Zombie verwandeln, wenn ich dies nicht auf FALSE setze!
Stattdessen habe ich diese ENV-Variablen vor dem Start von Apache festgelegt.
Wenn Sie unsicher sind, probieren Sie es aus, ob es funktioniert. */
var $OraPutEnv = true;

var $Database = "";
var $User = "";
var $PassWord = "";

var $Link_ID = 0;
var $Query_ID = 0;
var $Record = array();
var $Row;

var $Errno = 0;
var $Error = "";
var $ora_no_next_fetch=false;


/* der Vollständigkeit halber aus db_MySQL kopiert */
/* public: Identifikationskonstante. Ändere das niemals. */
var $type = "oracle";
var $revision = "Revision: 1.3";
var $Halt_On_Error = "yes"; ## „Ja“ (mit Meldung anhalten), „Nein“ (Fehler stillschweigend ignorieren), „Bericht“ (Fehler ignorieren, aber eine Warnung ausgeben)

/* public: Konstruktor */
Funktion DB_Sql($query = "") {
$this->query($query);
}

/* öffentlich: einige triviale Berichterstattung */
Funktion link_id() {
return $this->Link_ID;
}

Funktion query_id() {
return $this->Query_ID;
}

Funktion connect() {
## siehe oben, warum wir das tun
if ($this->OraPutEnv) {
PutEnv("ORACLE_SID=$this->Database");
PutEnv("ORACLE_HOME=$this->Home");
}
if ( 0 == $this->Link_ID ) {
if($this->Debug) {
printf("
Connect()ing to $this->Database...
n");
}
if($this->Remote) {
if($this->Debug) {
printf("
connect() $this->User/******@$this->Database
n");
}  
$this->Link_ID=ora_plogon
("$this->Benutzer/$this->Passwort@$this->Datenbank","");
/****************** (Kommentar von SSilk)
Das funktioniert auf meinem System nicht:
$this->Link_ID=ora_plogon
("$this->User@$this->Database.world","$this->Password");
***************/
} else {
if($this->Debug) {
printf("
connect() $this->Benutzer, $this->Passwort
n");
}  
$this->Link_ID=ora_plogon("$this->Benutzer","$this->Passwort");
/* (Kommentar von SSilk: Ich weiß nicht, wie das funktionieren könnte, aber ich lasse es unberührt!) */
}
if($this->Debug) {
printf("
connect() Link_ID: $this->Link_ID
n");
}
if (!$this->Link_ID) {
$this->halt("connect() Link-ID == false " .
"($this->Link_ID), ora_plogon fehlgeschlagen");
} else {
//echo "commit on

";
ora_commiton($this->Link_ID);
}
if($this->Debug) {
printf("
connect() Habe die Link_ID erhalten: $this->Link_ID
n");
}
## Connect-Abfrage ausführen
if ($this->ConnectQuery) {
$this->query($this->ConnectQuery);
}
}
}

## Um die Anzahl der Cursor pro System/Benutzer zu erhöhen, bearbeiten Sie das
## init.ora-Datei und erhöhen Sie den Parameter max_open_cursors. Deins ist auf
## der Standardwert, 100 pro Benutzer.
## Wir haben versucht, das Verhalten von query() so zu ändern, dass es
versucht ##, um Cursor zu sichern, aber seien Sie andererseits vorsichtig damit, dass Sie
## kein altes Ergebnis verwenden.
##  
## Sie können ->disconnect() auch ausgiebig nutzen!
## Die nicht verwendeten QueryIDs werden manchmal recycelt.  

Funktionsabfrage($Query_String)  
{

/* Bitte keine leere Abfrage. */
if (empty($Query_String))
{
0 zurückgeben;
}

$this->connect();
$this->lastQuery=$Query_String;

if (!$this->Query_ID) {
$this->Query_ID= ora_open($this->Link_ID);
}
if($this->Debug) {
printf("Debug: query = %s
n", $Query_String);
printf("
Debug: Query_ID: %d
n", $this->Query_ID);
}

if(!@ora_parse($this->Query_ID,$Query_String)) {
$this->Errno=ora_errorcode($this->Query_ID);
$this->Error=ora_error($this->Query_ID);
$this->halt("
ora_parse() failed:
$Query_String
Snap & paste this to sqlplus!");
} elseif (!@ora_exec($this->Query_ID)) {
$this->Errno=ora_errorcode($this->Query_ID);
$this->Error=ora_error($this->Query_ID);
$this->halt("
n$Query_Stringn
Einrasten und in sqlplus einfügen!");
}

$this->Row=0;

if(!$this->Query_ID) {
$this->halt("Ungültiges SQL: ".$Query_String);
}

return $this->Query_ID;
}

Funktion next_record() {
if (!$this->ora_no_next_fetch &&  
0 == ora_fetch($this->Query_ID)) {
if ($this->Debug) {
printf("
next_record(): ID: %d Zeile: %d
n",
$this->Query_ID,$this->Row 1);
// weitere Informationen zu $this->Row 1 ist $this->num_rows(),
// funktioniert aber nicht in allen Fällen (komplizierte Auswahl)
// und es ist hier sehr langsam
}
$this->Row =1;

$errno=ora_errorcode($this->Query_ID);
if(1403 == $errno) { # 1043 bedeutet, dass keine weiteren Datensätze gefunden wurden
$this->Errno=0;
$this->Error="";
$this->disconnect();
$stat=0;
} else {
$this->Error=ora_error($this->Query_ID);
$this->Errno=$errno;
if($this->Debug) {
printf("
%d Fehler: %s",
$this->Errno,
$this->Error);
}
$stat=0;
}
} else {
$this->ora_no_next_fetch=false;
for($ix=0;$ixQuery_ID);$ix ) {
$col=strtolower(ora_columnname($this->Query_ID,$ix));
$value=ora_getcolumn($this->Query_ID,$ix);
$this->Record[ "$col" ] = $value;
$this->Record[ $ix ] = $value;
#DBG echo"[$col]: $value
n";
}
$stat=1;
}

return $stat;
}

##seek() funktioniert nur für $pos - 1 und $pos
## Vielleicht mache ich eine eigene Implementierung, aber meine
## Meiner Meinung nach sollte dies mit PHP3 erledigt werden
Funktion see($pos) {
if ($this->Row - 1 == $pos) {
$this->ora_no_next_fetch=true;
} elseif ($this->Row == $pos ) {
## nichts tun
} else {
$this->halt("Ungültige Suche(): Die Position kann nicht von der API verarbeitet werden.
".
„In dieser Version ist nur eine Suche bis zum letzten Element zulässig
“.
„Unterschied zu groß. Gesucht: $pos Aktuelle Position: $this->Row“);
}
if ($this->Debug) echo "
Debug: see = $pos
";
$this->Row=$pos;
}

Funktionssperre($table, $mode = "write") {
if ($mode == "write") {
$result = ora_do($this->Link_ID, "Tabelle $table im zeilenexklusiven Modus sperren");
} else {
$result = 1;
}
$result zurückgeben;
}

Funktion unlock() {
return ora_do($this->Link_ID, "commit");
}

// Wichtiger Hinweis: Diese Funktion funktioniert nicht mit Oracle-Datenbank-Links!
// Es steht Ihnen frei, eine bessere Methode zu erhalten. :)
Funktionsmetadaten($table,$full=false) {
$count = 0;
$id = 0;
$res = array();

/*
* Aufgrund von Kompatibilitätsproblemen mit Table haben wir das Verhalten geändert
* von Metadaten();
* Abhängig von $full geben Metadaten die folgenden Werte zurück:
*
* – full ist falsch (Standard):
* $result[]:
* [0]["table"] Tabellenname
* [0]["name"] Feldname
* [0]["type"] Feldtyp
* [0]["len"] Feldlänge
* [0]["flags"] Feldflags ("NOT NULL", "INDEX")
* [0]["Format"] Genauigkeit und Skala der Zahl (z. B. "10,2") oder leer
* [0]["index"] Name des Index (falls vorhanden)
* [0]["chars"] Anzahl der Zeichen (falls vorhanden)
*
* – voll ist wahr
* $result[]:
* ["num_fields"] Anzahl der Metadatensätze
* [0]["table"] Tabellenname
* [0]["name"] Feldname
* [0]["type"] Feldtyp
* [0]["len"] Feldlänge
* [0]["flags"] Feldflags ("NOT NULL", "INDEX")
* [0]["format"] Genauigkeit und Skala der Zahl (z. B. "10,2") oder leer
* [0]["index"] Name des Index (falls vorhanden)
* [0]["chars"] Anzahl der Zeichen (falls vorhanden)
* [0]["php_type"] der entsprechende PHP-Typ
* [0]["php_subtype"] der Subtyp des PHP-Typs
* ["meta"][Feldname] Index des Feldes mit dem Namen "Feldname"
* Dies könnte verwendet werden, wenn Sie den Namen, aber keine Indexnummer haben – sehr schnell
* Test: if (isset($result['meta']['myfield'])) {} ...
*/

$this->connect();

## Dies ist ein RIGHT OUTER JOIN: „( )“, wenn Sie sehen möchten, was
## Diese Abfrageergebnisse versuchen Folgendes:
## $table = neue Tabelle; $db = new my_DB_Sql; # du musst
machen ## # deine eigene Klasse
## $table->show_results($db->query(see query vvvvvv))
##
$this->query("SELECT T.table_name,T.column_name,T.data_type,".
„T.data_length,T.data_precision,T.data_scale,T.nullable,“.
„T.char_col_decl_length,I.index_name“.
„FROM ALL_TAB_COLUMNS T,ALL_IND_COLUMNS I“.
„WHERE T.column_name=I.column_name ()“.
„ AND T.table_name=I.table_name ( )“.
" AND T.table_name=UPPER('$table') ORDER BY T.column_id");

$i=0;
while ($this->next_record()) {
$res[$i]["table"] = $this->Record[table_name];
$res[$i]["name"] = strtolower($this->Record[column_name]);
$res[$i]["type"] = $this->Record[data_type];
$res[$i]["len"] = $this->Record[data_length];
if ($this->Record[index_name]) $res[$i]["flags"] = "INDEX ";
$res[$i]["flags"] .= ( $this->Record[nullable] == 'N') ? '': 'NICHT NULL';
$res[$i]["format"]= (int)$this->Record[data_precision].",".
(int)$this->Record[data_scale];
if ("0,0"==$res[$i]["format"]) $res[$i]["format"]='';
$res[$i]["index"] = $this->Record[index_name];
$res[$i]["chars"] = $this->Record[char_col_decl_length];
if ($full) {
$j=$res[$i]["name"];
$res["meta"][$j] = $i;
$res["meta"][strtoupper($j)] = $i;
switch ($res[$i]["type"]) {
Fall „VARCHAR2“:
Fall „VARCHAR“ :
case „CHAR“ :
$res["php_type"]="string";
$res["php_subtype"]="";
brechen;
Fall „DATUM“ :
$res["php_type"]="string";
$res["php_subtype"]="Datum";
brechen;
Fall „BLOB“ :
Fall „CLOB“ :
Fall „BFILE“:
Fall „RAW“:
Fall „LONG“ :
Fall „LONG RAW“:
$res["php_type"]="string";
$res["php_subtype"]="blob";
brechen;
case „NUMBER“ :
if ($res[$i]["format"]) {
$res["php_type"]="double";
$res["php_subtype"]="";
} else {
$res["php_type"]="int";
$res["php_subtype"]="";
}
brechen;
Standard:
$this->halt("metadata(): Typ ist kein gültiger Wert: '$res[$i][type]'");
brechen;
}
}
if ($full) $res["meta"][$res[$i]["name"]] = $i;
$i ;
}
if ($full) $res["num_fields"]=$i;
# $this->disconnect();
return $res;
}

## DIESE FUNKTION IST NICHT GETESTET!
Funktion Affect_rows() {
if ($this->Debug) echo "
Debug: Affect_rows=". ora_numrows($this->Query_ID)."
";
return ora_numrows($this->Query_ID);
}

## Bekannte Fehler: Es funktioniert nicht für SELECT DISTINCT und alle
## andere Konstrukte, die von den resultierenden Zeilen abhängen.
## Sie müssen also *wirklich* jede von Ihnen gestellte Abfrage überprüfen, ob sie
ist ## wird damit funktionieren!
##
## Außerdem müssen Sie für einen qualifizierten Ersatz das
analysieren ## Auswahl, da dies fehlschlägt: „SELECT id, from FROM ...“).
## „from“ ist – soweit ich weiß ein Schlüsselwort in Oracle, also kann es
## darf nur auf diese Weise verwendet werden. Aber Sie wurden gewarnt.
Funktion num_rows() {
$curs=ora_open($this->Link_ID);

## Das ist der wichtige Teil und es ist auch der HACK!
if (eregi("^[[:space:]]*SELECT[[:space:]]",$this->lastQuery) )  
{

# Das funktioniert bei allen?? Fälle, einschließlich SELECT DISTINCT-Fall.
# Wir wählen einfach count(*) aus dem ursprünglichen SQL-Ausdruck
aus # und entfernen Sie ORDER BY (falls vorhanden), um die Geschwindigkeit zu erhöhen
# Ich mag auch reguläre Ausdrücke ;-)))  
$q = sprintf("SELECT COUNT(*) FROM (%s)",
@eregi_Replace("ORDER[[:space:]] BY[^)]*()*)", "1",  
$this->lastQuery)  
);

# funktioniert auch für Unterauswahlen:
# if (eregi("[[:space:]] FROM([[:space:]] .*[[:space:]] FROM)",$this->lastQuery,$r))
# $areplace=$r[1];
# $q=eregi_Replace("^[[:space:]]*SELECT[[:space:]] ".
# ".*[[:space:]] FROM",
# "SELECT COUNT(*) FROM$areplace",
# $this->lastQuery);

if ($this->Debug) echo "
Debug: num_rows: $q
";

ORA_parse($curs,$q);
ORA_exec($curs);
ORA_fetch($curs);
$result = ORA_getcolumn($curs,0);
ORA_close($curs);
if ($this->Debug)
{  
echo "
Debug: ID ".$this->QueryID.
" num_rows=". $result ."
";
}
$result zurückgeben;
}  
sonst  
{
$this->halt("Letzte Abfrage war keine SELECT: $this->lastQuery");
}
}

Funktion num_fields() {
if ($this->Debug) echo "
Debug: num_fields=". ora_numcols($this->Query_ID) . "
";
return ora_numcols($this->Query_ID);
}

Funktion nf() {
return $this->num_rows();
}

Funktion np() {
print $this->num_rows();
}

Funktion f($Name) {
return $this->Record[$Name];
}

Funktion p($Name) {
print $this->Record[$Name];
}

/* öffentlich: Sequenznummer */
Funktion nextid($seq_name)
{
$this->connect();

/* Unabhängige Abfrage_ID */
$Query_ID = ora_open($this->Link_ID);

if(!@ora_parse($Query_ID,"SELECT $seq_name.NEXTVAL FROM DUAL"))  
{
// Es gibt noch keine solche Sequenz, dann erstelle sie
if(!@ora_parse($Query_ID,"CREATE SEQUENCE $seq_name")  
||
!@ora_exec($Query_ID)
)
{
$this->halt("
nextid()-Funktion – Sequenz kann nicht erstellt werden");
0 zurückgeben;
}
@ora_parse($Query_ID,"SELECT $seq_name.NEXTVAL FROM DUAL");
}  
if (!@ora_exec($Query_ID)) {
$this->halt("
ora_exec() failed:
nextID function");
}
if (@ora_fetch($Query_ID) ) {
$next_id = ora_getcolumn($Query_ID, 0);
}
sonst {
$next_id = 0;
}
if ( $Query_ID > 0 ) {
ora_close($Query_ID);
}

return $next_id;
}

Funktion „disconnect()“ {
if($this->Debug) {
echo "Debug: Verbindung zu $this->Query_ID...
n wird getrennt";
}
if ( $this->Query_ID < 1 ) {
echo "Warnung: connected(): ID $this->Query_IDn kann nicht freigegeben werden";
# zurückkehren();
}
ora_close($this->Query_ID);
$this->Query_ID=0;
}

/* privat: Fehlerbehandlung */
Funktion halt($msg) {
if ($this->Halt_On_Error == "no")
zurückkehren;

$this->haltmsg($msg);

if ($this->Halt_On_Error != "report")
die("Sitzung angehalten.");
}

Funktion haltmsg($msg) {
printf("
Datenbankfehler: %s
n", $msg);
printf("Oracle-Fehler: %s (%s)
n",
$this->Errno,
$this->Error);
}

Funktion table_names() {
$this->connect();
$this->query("
SELECT Tabellenname, Tabellenbereichsname
FROM user_tables");
$i=0;
while ($this->next_record())
{
$info[$i]["table_name"] =$this->Record["table_name"];
$info[$i]["tablespace_name"]=$this->Record["tablespace_name"];
$i ;
}  
$info zurückgeben;
}


// Etwas Transaktionsunterstützung
// Methoden werden in ct_oracle.inc
verwendet Funktion begin_transaction()  
{
$this->connect();
// Jetzt Autocommit deaktivieren
Ora_CommitOff($this->Link_ID);
if ($this->Debug)
{
print „TRANSAKTION BEGINNEN
“;
}
}  
Funktion end_transaction()  
{
if ($this->Debug)
{
print „TRANSAKTION BEGINNEN
“;
}

$res = 1;
if(!@Ora_Commit($this->Link_ID))
{
Ora_CommitOn($this->Link_ID);
$this->halt("Transaktion konnte nicht abgeschlossen werden");
$res = 0;
}
// Autocommit erneut aktivieren
Ora_CommitOn($this->Link_ID);

if ($this->Debug)
{
print „TRANSAKTION ENDE: $res
“;
}
return $res;
}


}
?> 

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage