ホームページ  >  記事  >  バックエンド開発  >  php oracleデータベース関数ライブラリ

php oracleデータベース関数ライブラリ

WBOY
WBOYオリジナル
2016-08-08 09:33:46811ブラウズ

クラス DB_Sql {
var $Debug = false;
var $Home = "/u01/app/Oracle/PROduct/8.0.4";
var $Remote = 1;
/* このクエリは最初の接続後に直接送信されます
例:
var $ConnectQuery="ALTER セッション SET nls_date_ language=ドイツ語 nls_date_format='DD.MM.RRRR'";
->このセッションの日付形式を設定します。ora-role の場合はこれで問題ありません
変更できません */
var $ConnectQuery='';
/* Oracle 8.0.5、Apache、php3.0.6 での奇妙なエラーのため
私のシステム Apache では ENV を設定する必要はありません
これを FALSE に設定しないと、ゾンビに変わってしまいます。
代わりに、Apache の起動前にこれらの ENV 変数を設定します。
不明な場合は、うまくいくかどうか試してください。 */
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;


/* 完全を期すために db_MySQL からコピー */
/* public: 識別定数。これを決して変更しないでください。 */
var $type = "オラクル";
var $revision = "リビジョン: 1.3";
var $Halt_On_Error = "はい"; ## "yes" (メッセージを表示して停止)、"no" (エラーを静かに無視)、"report" (エラーを無視しますが、警告を吐きます)

/* パブリック: コンストラクター */
関数 DB_Sql($query = "") {
$this->クエリ($クエリ);
}

/* 公開: 些細なレポート */
関数 link_id() {
$this->Link_ID を返す;
}

関数クエリ ID() {
$this->Query_ID を返す;
}

関数 connect() {
## これを行う理由については上記を参照してください
if ($this->OraPutEnv) {
PutEnv("ORACLE_SID=$this->データベース");
PutEnv("ORACLE_HOME=$this->ホーム");
}
if ( 0 == $this->Link_ID ) {
if($this->デバッグ) {
printf("
$this->Database に接続()中...
n");
}
if($this->リモート) {
if($this->デバッグ) {
printf("
connect() $this->User/******@$this->データベース
n");
}
$this->Link_ID=ora_plogon
("$this->ユーザー/$this->パスワード@$this->データベース","");
/************** (SSilkさんのコメント)
これは私のシステムでは動作しません:
$this->Link_ID=ora_plogon
("$this->ユーザー@$this->Database.world","$this->パスワード");
***************/
} その他 {
if($this->デバッグ) {
printf("
connect() $this->ユーザー, $this->パスワード
n");
}
$this->Link_ID=ora_plogon("$this->ユーザー","$this->パスワード");
/* (SSilk によるコメント: これがどのように機能するかわかりませんが、このままにしておきます!) */
}
if($this->デバッグ) {
printf("
connect() リンク ID: $this->リンク ID
n");
}
if (!$this->Link_ID) {
$this->halt("connect() リンク ID == false " .
"($this->Link_ID)、ora_plogon が失敗しました");
} その他 {
//エコー "

にコミット";
ora_commiton($this->リンク_ID);
}
if($this->デバッグ) {
printf("
connect() Link_ID を取得しました: $this->Link_ID
n");
}
## 接続クエリを実行する
if ($this->ConnectQuery) {
$this->クエリ($this->ConnectQuery);
}
}
}

## システム/ユーザーごとのカーソルの数を増やすには、
を編集してください。 ## init.ora ファイルを作成し、max_open_cursors パラメータを増やします。あなたのものがオンになっています
## デフォルト値はユーザーごとに 100 です。
## 私たちは、ある方法で query() の動作を変更しようとしました
## カーソルを安全にするためですが、その一方で、これには注意してください
## 古い結果は使用しないでください。
##
## ->disconnect() を広範囲に使用することもできます。
## 未使用の QueryID は時々リサイクルされます。  

関数クエリ($Query_String)
{

/* 空のクエリは使用しないでください。 */
if (空($Query_String))
{
0を返します。
}

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

if (!$this->Query_ID) {
$this->Query_ID= ora_open($this->Link_ID);
}
if($this->デバッグ) {
printf("デバッグ: クエリ = %s
n", $Query_String);
printf("
デバッグ: クエリ ID: %d
n", $this->クエリ 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() が失敗しました:
$Query_String
これをスナップして 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
これをスナップして sqlplus に貼り付けます!");
}

$this->行=0;

if(!$this->Query_ID) {
$this->halt("無効な SQL: ".$Query_String);
}

$this->Query_ID を返す;
}

関数 next_record() {
if (!$this->ora_no_next_fetch &&
0 == ora_fetch($this->Query_ID)) {
if ($this->デバッグ) {
printf("
next_record(): ID: %d 行: %d
n",
$this->Query_ID,$this->Row+1);
// $this->Row+1 の詳細は $this->num_rows(),
// ただし、すべての場合に機能するとは限りません (複雑な選択)
// ここでは非常に遅いです
}
$this->行 +=1;

$errno=ora_errorcode($this->Query_ID);
if(1403 == $errno) { # 1043 は、これ以上レコードが見つからないことを意味します
$this->Errno=0;
$this->エラー="";
$this->disconnect();
$stat=0;
} その他 {
$this->Error=ora_error($this->Query_ID);
$this->Errno=$errno;
if($this->デバッグ) {
printf("
%d エラー: %s",
$this->エラー、
$this->エラー);
}
$stat=0;
}
} その他 {
$this->ora_no_next_fetch=false;
for($ix=0;$ixQuery_ID);$ix++) {
$col=strto lower(ora_columnname($this->Query_ID,$ix));
$value=ora_getcolumn($this->Query_ID,$ix);
$this->Record[ "$col" ] = $value;
$this->レコード[ $ix ] = $value;
#DBG echo"[$col]: $value
n";
}
$stat=1;
}

$stat を返します。
}

## Seek() は $pos - 1 と $pos に対してのみ機能します
## おそらく独自の実装を作成しますが、私の
## 意見としては、これは PHP3 で行うべきだということです
関数シーク($pos) {
if ($this->Row - 1 == $pos) {
$this->ora_no_next_fetch=true;
elseif ($this->Row == $pos ) {
##何もしないでください
} その他 {
$this->halt("無効なseek(): 位置はAPIで処理できません。
".
「このバージョンでは、最後の要素へのシークのみが許可されます
」。
"差が大きすぎます。募集: $pos 現在の位置: $this->Row");
}
if ($this->Debug) echo "
デバッグ: シーク = $pos
";
$this->Row=$pos;
}

関数ロック($table, $mode = "書き込み") {
if ($mode == "書き込み") {
$result = ora_do($this->Link_ID, "行排他モードでテーブル $table をロック");
} その他 {
$結果 = 1;
}
$result を返します。
}

関数ロック解除() {
return ora_do($this->Link_ID, "コミット");
}

// 重要な注意: この関数は Oracle-Database-Links では機能しません。
// より良いメソッドを自由に入手できます。 :)
関数メタデータ($table,$full=false) {
$count = 0;
$id = 0;
$res = 配列();

/*
* テーブルとの互換性の問題のため、動作を変更しました
* のメタデータ();
* $full に応じて、メタデータは次の値を返します:
*
* - full は false (デフォルト):
* $結果[]:
* [0]["table"] テーブル名
* [0]["name"] フィールド名
* [0]["type"] フィールドの種類
* [0]["len"] フィールドの長さ
* [0]["flags"] フィールドのフラグ ("NOT NULL"、"INDEX")
* [0]["format"] 数値の精度とスケール (例: "10,2") または空
* [0]["index"] インデックスの名前 (存在する場合)
* [0]["chars"] 文字数 (文字型がある場合)
*
* - フルは真実です
* $result[]:
* ["num_fields"] メタデータ レコードの数
* [0]["table"] テーブル名
* [0]["name"] フィールド名
* [0]["type"] フィールドの種類
* [0]["len"] フィールドの長さ
* [0]["flags"] フィールドのフラグ ("NOT NULL"、"INDEX")
* [0]["format"] 数値の精度とスケール (例: "10,2") または空
* [0]["index"] インデックスの名前 (存在する場合)
* [0]["chars"] 文字数 (文字型がある場合)
* [0]["php_type"] 対応する PHP タイプ
* [0]["php_subtype"] PHP タイプのサブタイプ
* ["meta"][フィールド名] "フィールド名" という名前のフィールドのインデックス
* これは、名前はあるがインデックス番号がない場合に使用できます - 非常に高速です
* テスト: if (isset($result['meta']['myfield'])) {} ...
*/

$this->connect();

## これは右外部結合です: "(+)"、見たい場合は、何
## このクエリの結果は次のことを試してください:
## $table = 新しいテーブル; $db = 新しい my_DB_Sql; #作らなきゃ
## # あなた自身のクラス
## $table->show_results($db->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]["テーブル"] = $this->レコード[テーブル名];
$res[$i]["name"] = strto lower($this->Record[column_name]);
$res[$i]["type"] = $this->Record[data_type];
$res[$i]["len"] = $this->レコード[データ長];
if ($this->Record[index_name]) $res[$i]["flags"] = "INDEX ";
$res[$i]["flags"] .= ( $this->Record[nullable] == 'N') ? '' : 'NOT NULL';
$res[$i]["format"]= (int)$this->Record[data_precision].",".
(int)$this->レコード[データスケール];
if ("0,0"==$res[$i]["format"]) $res[$i]["format"]='';
$res[$i]["インデックス"] = $this->レコード[インデックス名];
$res[$i]["chars"] = $this->Record[char_col_decl_length];
if ($full) {
$j=$res[$i]["名前"];
$res["メタ"][$j] = $i;
$res["meta"][strtoupper($j)] = $i;
スイッチ ($res[$i]["タイプ"]) {
ケース "VARCHAR2" :
ケース "VARCHAR" :
ケース「CHAR」:
$res["php_type"]="文字列";
$res["php_subtype"]="";
壊す;
ケース「日付」:
$res["php_type"]="文字列";
$res["php_subtype"]="日付";
壊す;
ケース「BLOB」:
ケース「CLOB」:
ケース「BFILE」:
「RAW」の場合:
ケース「ロング」:
ケース「LONG RAW」:
$res["php_type"]="文字列";
$res["php_subtype"]="ブロブ";
壊す;
ケース「番号」:
if ($res[$i]["フォーマット"]) {
$res["php_type"]="double";
$res["php_subtype"]="";
} その他 {
$res["php_type"]="int";
$res["php_subtype"]="";
}
壊す;
デフォルト:
$this->halt("metadata(): タイプが有効な値ではありません: '$res[$i][type]'");
壊す;
}
}
if ($full) $res["meta"][$res[$i]["name"]] = $i;
$i++;
}
if ($full) $res["num_fields"]=$i;
# $this->disconnect();
$res を返します。
}

## この関数はテストされていません!
関数影響を受ける_rows() {
if ($this->Debug) echo "
Debug:affected_rows="。 ora_numrows($this->Query_ID)."
";
return ora_numrows($this->Query_ID);
}

## 既知のバグ: SELECT DISTINCT およびその他の
では機能しません ## 結果の行に依存するその他の構成要素。
## したがって、作成するすべてのクエリを *本当に必要* にする必要があります
## も使えます!
##
## また、適格な置換を行うには、
を解析する必要があります。 ## 選択、これは失敗します: "SELECT id, from FROM ...")。
## "from" は - 私が Oracle のキーワードを知っている限り、それは可能です
## この方法でのみ使用してください。しかし、あなたは警告を受けています。
関数 num_rows() {
$curs=ora_open($this->リンク_ID);

## これは重要な部分であり、ハックでもあります。
if (eregi("^[[:space:]]*SELECT[[:space:]]",$this->lastQuery) )
{

#これは誰にとってもうまくいきますか? SELECT DISTINCT ケースを含むケース。
# 元の SQL 式から select count(*) を作成するだけです
# スピードを上げるために ORDER BY (存在する場合) を削除します
# 正規表現も好きです ;-)))
$q = sprintf("SELECT COUNT(*) FROM (%s)",
@eregi_Replace("ORDER[[:space:]]+BY[^)]*()*)", "1",
$this->lastQuery)
);

# 副選択でも機能します:
# 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->デバッグ)
{
echo "
デバッグ: ID ".$this->QueryID。
「 num_rows 」。 $result ."
";
}
$result を返します。
}
その他
{
$this->halt("最後のクエリは SELECT ではありませんでした: $this->lastQuery");
}
}

関数 num_fields() {
if ($this->Debug) echo "
Debug: num_fields="。 ora_numcols($this->Query_ID) 。 "
";
return ora_numcols($this->Query_ID);
}

関数 nf() {
$this->num_rows(); を返します。
}

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

関数 f($Name) {
$this->レコード[$Name]を返します;
}

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

/* public: シーケンス番号 */
関数 nextid($seq_name)
{
$this->connect();

/* 独立したクエリ ID */
$Query_ID = ora_open($this->リンク_ID);

if(!@ora_parse($Query_ID,"SELECT $seq_name.NEXTVAL FROM DUAL"))
{
// そのようなシーケンスはまだないので、作成します
if(!@ora_parse($Query_ID,"CREATE SEQUENCE $seq_name")
||
!@ora_exec($Query_ID)
)
{
$this->halt("
nextid() 関数 - シーケンスを作成できません");
0を返します。
}
@ora_parse($Query_ID,"SELECT $seq_name.NEXTVAL FROM DUAL");
}
if (!@ora_exec($Query_ID)) {
$this->halt("
ora_exec() が失敗しました:
nextID 関数");
}
if (@ora_fetch($Query_ID) ) {
$next_id = ora_getcolumn($Query_ID, 0);
}
他 {
$next_id = 0;
}
if ( $Query_ID > 0 ) {
ora_close($Query_ID);
}

$next_id を返します;
}

関数切断() {
if($this->デバッグ) {
echo "デバッグ: $this->Query_ID を切断しています...
n";
}
if ( $this->Query_ID < 1 ) {
echo "警告:切断():ID $this->Query_IDnを解放できません";
# 戻る();
}
ora_close($this->Query_ID);
$this->Query_ID=0;
}

/* プライベート: エラー処理 */
関数停止($msg) {
if ($this->Halt_On_Error == "いいえ")
戻る;

$this->haltmsg($msg);

if ($this->Halt_On_Error != "レポート")
die("セッションが停止されました。");
}

関数 haltmsg($msg) {
printf("
データベースエラー: %s
n", $msg);
printf("Oracle エラー: %s (%s)
n",
$this->エラー、
$this->エラー);
}

関数テーブル名() {
$this->connect();
$this->query("
SELECT テーブル名、テーブルスペース名
ユーザーテーブルから");
$i=0;
while ($this->next_record())
{
$info[$i]["テーブル名"] =$this->Record["テーブル名"];
$info[$i]["テーブルスペース名"]=$this->Record["テーブルスペース名"];
$i++;
}
$info を返します。
}


// いくつかのトランザクションのサポート
// メソッドは ct_oracle.inc で使用されます
関数 begin_transaction()
{
$this->connect();
// 次に、自動コミットを無効にします
Ora_CommitOff($this->Link_ID);
if ($this->デバッグ)
{
print "トランザクションを開始
";
}
}
関数 end_transaction()
{
if ($this->デバッグ)
{
print "トランザクションを開始
";
}

$res = 1;
if(!@Ora_Commit($this->Link_ID))
{
Ora_CommitOn($this->Link_ID);
$this->halt("トランザクションを終了できません");
$res = 0;
}
// 自動コミットを再度有効にする
Ora_CommitOn($this->Link_ID);

if ($this->デバッグ)
{
print "トランザクション終了 : $res
";
}
$res を返します。
}


}
?> 

以上は php の oracle リソース関数を介したもので、さまざまな内容が含まれており、PHP の教義に関心のある友人の助けになることを望みます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。