oracle|データ|データベース|オリジナル
私は仕事上の関係で Oracle データベースを使用していますが、ここではあまり使用していないことがわかりました。しかし、PHP での ORACLE データベースの操作に関する一部の質問に答えられないことがよくあります。私もいくつか質問しましたが、答えられませんでした。 1 人が回答したので、Oracle データベースを使用する人々のお役に立てればと思い、仕事で蓄積したスキルと経験の一部を捧げることにしました。
1. 構成環境:
Oracle8 以降のデータベースにアクセスするには、Oracle8 Call-Interface (OCI8) が必要です。この拡張モジュールには Oracle8 クライアント関数ライブラリが必要なので、リモートの Oracle データベースに接続する場合は、Oracle のクライアント ソフトウェアもインストールする必要があります。Oracle のクライアント ソフトウェアは、Oracle の Web サイト (http://www.oracle.com) から無料でダウンロードできます。 , こちら これは多くの初心者が見落としがちなことなので、この記事を読んだ人はフォーラムで「Oracle データベースに接続できないのはなぜですか?」などの質問をしないでください。
(1) まず Oracle8i クライアントがインストールされていることを確認し、次に net8 アシスタント (クライアント ソフトウェアによって提供される) を使用してサービス名を作成します。サービス名は Oracle データベースの SID であり、クエリによって取得できることに注意してください。 initsid ファイル内のserver_names。
(2) php.ini の ;extension=php_oci8.dll の前にあるコメント記号「;」を削除して、php が Oracle
をサポートするモジュールをロードできるようにします。そして、php_oci8.dll を Windows2000 サーバーのインストール ディレクトリの下の system32 サブディレクトリにコピーします。たとえば、d:winntsystem32 の場合は、マシンを再起動します。
(3) 正しく接続できるかどうかを確認するためのテスト ファイルを作成します (サービス名 sid が test の場合):
ここでの scott ユーザーは Oracle 独自のものであり、次のファイルを自分で作成する必要はありません。 WEB ルート ディレクトリ 以上です。データベース内のデータが表示されている場合は、接続が正常であることを意味します。そうでない場合は、前の手順で何が間違っていたかを確認する必要があります。
test.php
$dbconn=OCILogon("scott","tiger","test");
$sql ="select * from emp";
$stmt = OCIParse($dbconn, $sql) ;
if(!$stmt) {
echo "
エラー - SQL ステートメントを解析できませんでした。
"
}
OCIExecute($stmt)
while( , &$result_array) )
{
echo
"EMPno=$result_array[0];Ename=$result_array[1];JOB=$result_array[2];MGR=$result_array[3]
";
}
?>
2. PHP を使用して Oracle ストアド プロシージャを実行する
(1) sqlplus で接続した後、ストアド プロシージャを作成します:
CREATE OR REPLACE PROCEDURE inoutdemo (
par_in IN VARCHAR2,
par_in_out IN OUT VARCHAR2,
) par_out OUT VARCHAR2)
IS
BEGIN
par_out := par_in;
par_in_out := par_in || ' ' || par_in_out;
END;
(2) PHP ファイル:
sptest.php
//:inは入力変数、:inout は入力変数、:out は出力変数です。具体的な説明については、Oracle の PL/SQL マニュアルを参照してください
$conn=OCILogon("scott","tiger","test") ;
$stmt = OCIParse ($conn,"BEGIN inoutdemo(:in,:inout,:out); END;");
OCIBindByName($stmt,":in",$in,32);
OCIBindByName($ stmt,":inout" ,$inout,32);
OCIBindByName($stmt,":out",$out,32);
$in = "こんにちは ";
$inout = "世界!";
OCIExecute($stmt);
echo "
gt;
";
echo "in=".$in."
";
echo "inout=".$inout."
echo " out=".$out."
";
?>
3. Oracle データベースのページング
Oracle には Mysql のように非常に便利な制限がありませんが、独自の処理メソッドを備えた特別な rownum は、ページネーションにおいて非常に重要な役割を果たします。ページネーションにはさまざまな方法がありますが、最も一般的に使用されるのはマイナスです。
n1-n2 レコードを表示したい場合は、次のように記述できます:
(1) SELECT * FROM tablename WHERE rownum 注: このステートメントでは Order by は使用できません。そうでない場合は、エラーが報告されます。
(2) ポインターを下に移動する方法は次のとおりです:
ここで: $page は現在のページ、$pagesize は各ページに表示されるレコードの数です
for($i=0;$i<($page) -1)*$pagesize ;$i++)
{
@ocifetch($stmt);
}
次に、ocifetch($stmt) を使用して、表示したいレコードであるデータを取得します
(3) 複雑なクエリの場合ステートメントを使用し、 order by を使用してsortする場合は、次のメソッドを使用して解決できます:
SELECT TABLE_NAME,TABLE_TYPE FROM( SELECT ROWNUM ROWSEQ,X.* FROM (SELECT * FROM CAT ORDER BY
TABLE_TYPE) X) WHERE ROWSEQ BETWEEN n1+ 1 と n2;
私のお気に入りは 3 番目のタイプです。誰でも使用できるので、とても便利です。ふふ。
他の方法は非常に面倒で、Oracle カーソルなどを使用するため、PHP には適していません。
4. 特殊文字の挿入処理
一重引用符'など一部の文字はOracleのaddslashesでは処理できませんが、OracleのCHR関数を使用するか、一重引用符を追加することで可能です
。
例: SQL>insert into table names('it'||chr(39)||'s a test'));
または SQL>insert into table names('it's a test'));
表示:
it's a test.
5. PHP と Oracle のトランザクション処理
OCIExecute() 関数: int OCIExecute ( int ステートメント [, int 2 つの第 2 パラメータ モードがあります。デフォルトは OCI_COMMIT_ON_SUCCESS ですが、これは省略できます。 OCI_DEFAULT は、自動送信ではなく、トランザクション (Transation)
を使用した送信を意味します。
プログラム内に同時に正常に実行する必要があるデータベース操作ステートメントが 2 つあり、そのうちの 1 つが失敗してロールバックする必要がある場合は、次のように記述できます:
$conn=OCILogon($username, $password,$sid);
/ /最初の文
$Sql = "テーブル名の値に挿入()";
$stmt=OCIParse($conn,$Sql);
$result=OCIExecute($stmt, OCI_DEFAULT);
if (!$result) {
OCIRollback($conn);// 失敗した場合はロールバック
OCIFreeStatement($stmt); // リソースを解放します
OCILogoff($conn);
}
// 2 番目の文
$Sql = "更新テーブル名セット.." ;
$stmt=OCIParse($conn,$Sql);
$result=OCIExecute($stmt, OCI_DEFAULT);
if (!$result) {
OCIRollback($conn);//失敗した場合は、rollback
OCIFreeStatement ($stmt); // リソースを解放します
OCILogoff($conn);
}
OCICommit($conn) // 成功した場合は、送信します
OCIFreeStatement($stmt);
OCILogoff($conn );
6. PHP を使用して Oracle の LOB 型データを操作します (画像の保存と表示処理を含む)
PHP プログラマにとって、Oracle で最も面倒なことは、LOB を使用して画像を処理することです。
1. PHP 操作 BLOB:
まず画像を保存するテーブルを作成します。ユーザーがアップロードした画像ファイルは BLOB に保存されます
CREATE TABLE PICTURES (
ID NUMBER,
IMGTYPE, VARCHAR2(60),
DESCRIPTION VARCHAR2(100),
PICTURE BLOB
); ID の自動増加を実現したい場合は、別の SEQUENCE を作成します:
CREATE SEQUENCE PIC_SEQ;
PHP プログラム挿入部分:
$conn=OCILogon($username,$password,$sid);
// ここで注意すべき 2 つの点: まず、次のようにします。 EMPTY_BLOB()関数。これは Oracle の内部関数
//Number で、LOB ロケーターを返します。 LOB を挿入する場合、このメソッドを使用できるのは、最初に
//空の LOB ロケーターを生成し、次にこのロケーターを操作する場合のみです。 EMPTY_BLOB() 関数は
用です。//BLOB 型の場合、CLOB に対応するのは EMPTY_CLOB() です。 2 番目は RETURNING の後の
// 部分で、PHP の OCI 関数が処理できるように画像を返します。
$stmt = OCIParse($conn,"INSERT INTO PICTURES (id, imgtype,description, picture) VALUES
(PIC_SEQ.NEXTVAL, '$imgtype','$description', '$lob_upload_type', EMPTY_BLOB()) RETURNING picture
INTO :PICTURE");
//ローカル LOB オブジェクトの記述子を生成します。関数の 2 番目のパラメータ OCI_D_LOB に注意してください。
//LOB オブジェクトの生成を示します。その他の可能性としては、それぞれ BFILE オブジェクトと ROWID オブジェクトに対応する OCI_D_FILE および OCI_D_ROWID があります。
$lob = OCINewDescriptor($conn, OCI_D_LOB);
//生成された LOB オブジェクトを、前の SQL 文によって返されたロケータにバインドします。
OCIBindByName($stmt, ':PICTURE', &$lob, -1, OCI_B_BLOB);
OCIExecute($stmt); 方法 1: データを LOB オブジェクトに保存します。ここでのソース データはファイルであるため、LOB オブジェクトの savefile() メソッドが直接使用されます。 LOB
オブジェクトのその他のメソッドには、save() と load() があり、それぞれデータの保存と取得に使用されます。ただし、BFILE タイプには save()
if($lob->savefile($lob_upload)){
OCICommit($conn);
echo "アップロード成功
"; という 1 つのメソッドしかありません。 "アップロードに失敗しました
}
//方法 2: SAVE メソッドを使用して保存します
//$fp = fopen($lob_upload, "r");
//$File->save($ fp, filesize($lob_upload)));
//fclose($fp );
//LOB オブジェクトを解放します
OCIFreeDesc($stmt);
OCILogoff($conn); ;
ヒント: ファイルがデータ ライブラリに保存されているかどうかを確認するには、sqlplus の select dbms_lob.getlength(picture) を使用するか、PHP プログラムの strlen() 関数を使用します。
PHPプログラム - 表示部分(getpicture.php):
$conn = OCILogon($username, $password, $sid);
$stmt = OCIParse($conn,"SELECT imgtype,picture FROM PICTURES WHERE) ID=$pictureid");
if (OCIFetchInto($stmt, $result))
{
Header("Content-type: ".$result[0]);
echo $result[1]->load( );
}
//strlen($result[1]->load()) を使用して画像のサイズをチェックし、画像がデータベースに正しく保存されているかどうかを判断できます。
?>
画像を表示する必要がある場合は、次の操作を行うだけです:
画像が表示されます。
一部のオンライン記事では、記述子の代わりに LOB 値を返す方法が使用されていますが、試してみることはできません。
if (OCIFetchInto($stmt, $result, OCI_ASSOC+OCI_RETURN_LOBS)) )
{
echo "コンテンツ タイプ: " . StripSlashes($result[imgtype]);
echo StripSlashes($result[picture]); PHP 操作 CLOB:
Oracle には、可変長文字列を表すために使用される VARCHAR2 というデータ型があります。 VARCHAR2 は、Oracle が推奨するタイプでもあります。しかし、
VARCHAR2 の使用には問題があります。VARCHAR2 は最大 4000 文字しか表現できず、これは中国語の 2000 文字に相当します。プログラム内の文字列の長さが漢字 2000 文字を超える場合、VARCHAR2 は要件を満たすことができません。現時点では、CLOB の使用を試すことができます。 CLOB および BLOB の最大長は 4GB です。
以下は例です(PHP英語版マニュアル参照):
//保存するテキスト
$clobtext="異なるdr2";
//db connection
$conn = OCIlogon(" user" ,"pw","TNS");
//ここでの元の例ではストアド プロシージャを使用していますが、上記の方法を使用して BLOB を操作することもできます。
//例: $stmt = OCIParse($conn,"INSERT INTO table (id, clobtext) VALUES (text.NEXTVAL,,
EMPTY_CLOB()) RETURNING clobtext INTO :clob"); " begin tempclobtest_package.saveclob(:clob); end;";
$clob = OCINewDescriptor($conn, OCI_D_LOB);
$stmt = OCIParse($conn, $sql);
OCIBindByName ($stmt,': clob ', &$clob , -1,OCI_B_CLOB );
if(!OCIExecute($stmt, OCI_DEFAULT)) {print_r(OCIError($stmt));}
else{echo "送信成功";}
if ( $clob->save($clobtext))
{
OCICommit($conn);
echo "送信成功";
}
else
{
print_r(OCIError($stmt));
}
//リソースのリリース
$clob->free();
OCIFreeStatement($stmt);
?>