Forum und email

오라클 함수

소개

이 함수는 Oracle Call Interface (OCI)를 사용하여 오라클 10, 오라클 9, 오라클 8, 오라클 7 데이터베이스에 접근할 수 있도록 해줍니다. PHP 변수를 오라클 위치보유자에 넣을 수 있고, LOB, FILE, ROWID를 완전히 지원하며, 사용자 지정 변수를 사용할 수 있게 해줍니다.

요구 조건

이 확장을 사용하려면 오라클 클라이언트 라이브러리가 필요합니다. 윈도우 사용자는 php_oci8.dll을 사용하기 위해서 버전 10 이상의 라이브러리가 필요합니다.

필요한 모든 파일을 설치하는 가장 편리한 방법은 오라클 인스턴트 클라이언트를 사용하는 것으로, 다음 위치에서 받을 수 있습니다: » https://www.oracle.com/technology/tech/oci/instantclient/instantclient.html "기본" 버전의 오라클 인스턴트 클라이언트로도 OCI8 모듈을 사용하기에 충분합니다. 인스턴트 클라이언트는 ORACLE_SID나 ORACLE_HOME 환경 변수를 설정할 필요가 없습니다. 그러나 LD_LIBRARY_PATH와 NLS_LANG은 설정해야 합니다.

이 확장을 사용하기 전에, 오라클 사용자와 웹 데몬 사용자에 대하여 오라클 환경 변수를 정확하게 지정했는지 확인해야 합니다. 이 변수는 웹 서버를 시작하기 전에 설정해야 합니다. 설정해야할 변수는 다음과 같습니다:

  • ORACLE_HOME
  • ORACLE_SID
  • LD_PRELOAD
  • LD_LIBRARY_PATH
  • NLS_LANG
TNS_ADMIN, TWO_TASK, ORA_TZFILE처럼 자주 사용하지 않는 오라클 환경 변수와 ORA_NLS33, ORA_NLS10, NLS_* 등과 같은 다양한 오라클 세계화 설정은 오라클 문서를 참고하십시오.

웹 서버 사용자에 맞게 환경 변수를 적용한 후에, 오라클 그룹에도 웹 서버 사용자(nobody, www)를 추가해야 합니다.

Note: 웹서버가 시작되지 않거나 시작 시에 충돌하면 아파치가 pthread 라이브러리에 링크되어있는지 확인:

# ldd /www/apache/bin/httpd 
    libpthread.so.0 => /lib/libpthread.so.0 (0x4001c000)
    libm.so.6 => /lib/libm.so.6 (0x4002f000)
    libcrypt.so.1 => /lib/libcrypt.so.1 (0x4004c000)
    libdl.so.2 => /lib/libdl.so.2 (0x4007a000)
    libc.so.6 => /lib/libc.so.6 (0x4007e000)
    /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

libpthread가 보이지 않으면 아파치를 다시 설치해야 합니다:
# cd /usr/src/apache_1.3.xx
# make clean
# LIBS=-lpthread ./config.status
# make
# make install

UnixWare 같은 몇몇 시스템에서는 libpthread 대신에 libthread를 사용합니다. PHP와 아파치는 EXTRA_LIBS=-lthread로 설정해야 합니다.

실행시 설정

이 함수의 작동은 php.ini 설정에 영향을 받습니다.

OCI8 Configuration Options
Name Default Changeable Changelog
oci8.privileged_connect "0" PHP_INI_SYSTEM Available since PHP 5.1.2.
oci8.max_persistent "-1" PHP_INI_SYSTEM Available since PHP 5.1.2.
oci8.persistent_timeout "-1" PHP_INI_SYSTEM Available since PHP 5.1.2.
oci8.ping_interval "60" PHP_INI_SYSTEM Available since PHP 5.1.2.
oci8.statement_cache_size "20" PHP_INI_SYSTEM Available since PHP 5.1.2.
oci8.default_prefetch "10" PHP_INI_SYSTEM Available since PHP 5.1.2.
oci8.old_oci_close_semantics "0" PHP_INI_SYSTEM Available since PHP 5.1.2.

위 설정 지시어에 대한 간단한 설명입니다.

oci8.privileged_connect boolean

This option enables privileged connections using external credentials (OCI_SYSOPER, OCI_SYSDBA).

oci8.max_persistent int

The maximum number of persistent OCI8 connections per process. Setting this option to -1 means that there is no limit.

oci8.persistent_timeout int

The maximum length of time (in seconds) that a given process is allowed to maintain an idle persistent connection. Setting this option to -1 means that idle persistent connections will be maintained forever.

oci8.ping_interval int

The length of time (in seconds) that must pass before issuing a ping during oci_pconnect(). When set to 0, persistent connections will be pinged every time they are reused. To disable pings completely, set this option to -1.

Note: Disabling pings will cause oci_pconnect() calls to operate at the highest efficiency, but may cause PHP to not detect faulty connections, such as those caused by network partitions, or if the Oracle server has gone down since PHP connected, until later in the script. Consult the oci_pconnect() documentation for more information.

oci8.statement_cache_size int

This option enables statement caching, and specifies how many statements to cache. To disable statement caching just set this option to 0.

Note: A larger cache can result in improved performance, at the cost of increased memory usage.

oci8.default_prefetch int

This option enables statement prefetching and sets the default number of rows that will be fetched automatically after statement execution.

Note: A larger prefetch can result in improved performance, at the cost of increased memory usage.

oci8.old_oci_close_semantics boolean

This option controls oci_close() behaviour. Enabling it means that oci_close() will do nothing; the connection will not be closed until the end of the script. This is for backward compatibility only. If you find that you need to enable this setting, you are strongly encouraged to remove the oci_close() calls from your application instead of enabling this option.

예약 상수

이 확장은 다음의 상수들을 정의합니다. 이 확장을 PHP에 내장했거나, 실행시에 동적으로 읽어들일 경우에만 사용할 수 있습니다.

OCI_DEFAULT (integer)
Statement execution mode. Statement is not committed automatically when using this mode.
OCI_DESCRIBE_ONLY (integer)
Statement execution mode. Use this mode if you don't want to execute the query, but get the select-list's description.
OCI_COMMIT_ON_SUCCESS (integer)
Statement execution mode. Statement is automatically committed after oci_execute() call.
OCI_EXACT_FETCH (integer)
Statement fetch mode. Used when the application knows in advance exactly how many rows it will be fetching. This mode turns prefetching off for Oracle release 8 or later mode. Cursor is cancelled after the desired rows are fetched and may result in reduced server-side resource usage.
OCI_SYSDATE (integer)
OCI_B_BFILE (integer)
Used with oci_bind_by_name() when binding BFILEs.
OCI_B_CFILEE (integer)
Used with oci_bind_by_name() when binding CFILEs.
OCI_B_CLOB (integer)
Used with oci_bind_by_name() when binding CLOBs.
OCI_B_BLOB (integer)
Used with oci_bind_by_name() when binding BLOBs.
OCI_B_ROWID (integer)
Used with oci_bind_by_name() when binding ROWIDs.
OCI_B_CURSOR (integer)
Used with oci_bind_by_name() when binding cursors, previously allocated with oci_new_descriptor().
OCI_B_NTY (integer)
Used with oci_bind_by_name() when binding named data types. Note: in PHP < 5.0 it was called OCI_B_SQLT_NTY.
OCI_B_BIN (integer)
SQLT_BFILEE (integer)
The same as OCI_B_BFILE.
SQLT_CFILEE (integer)
The same as OCI_B_CFILEE.
SQLT_CLOB (integer)
The same as OCI_B_CLOB.
SQLT_BLOB (integer)
The same as OCI_B_BLOB.
SQLT_RDD (integer)
The same as OCI_B_ROWID.
SQLT_NTY (integer)
The same as OCI_B_NTY.
SQLT_LNG (integer)
Used with oci_bind_by_name() to bind LONG values.
SQLT_LBI (integer)
Used with oci_bind_by_name() to bind LONG RAW values.
SQLT_BIN (integer)
Used with oci_bind_by_name() to bind RAW values.
SQLT_NUM (integer)
Used with oci_bind_array_by_name() to bind arrays of NUMBER.
SQLT_INT (integer)
Used with oci_bind_array_by_name() to bind arrays of INTEGER.
SQLT_AFC (integer)
Used with oci_bind_array_by_name() to bind arrays of CHAR.
SQLT_CHR (integer)
Used with oci_bind_array_by_name() to bind arrays of VARCHAR2. Also used with oci_bind_by_name().
SQLT_VCS (integer)
Used with oci_bind_array_by_name() to bind arrays of VARCHAR.
SQLT_AVC (integer)
Used with oci_bind_array_by_name() to bind arrays of CHARZ.
SQLT_STR (integer)
Used with oci_bind_array_by_name() to bind arrays of STRING.
SQLT_LVC (integer)
Used with oci_bind_array_by_name() to bind arrays of LONG VARCHAR.
SQLT_FLT (integer)
Used with oci_bind_array_by_name() to bind arrays of FLOAT.
SQLT_ODT (integer)
Used with oci_bind_array_by_name() to bind arrays of LONG.
SQLT_BDOUBLE (integer)
SQLT_BFLOAT (integer)
OCI_FETCHSTATEMENT_BY_COLUMN (integer)
Default mode of oci_fetch_all().
OCI_FETCHSTATEMENT_BY_ROW (integer)
Alternative mode of oci_fetch_all().
OCI_ASSOC (integer)
Used with oci_fetch_all() and oci_fetch_array() to get an associative array as a result.
OCI_NUM (integer)
Used with oci_fetch_all() and oci_fetch_array() to get an enumerated array as a result.
OCI_BOTH (integer)
Used with oci_fetch_all() and oci_fetch_array() to get an array with both associative and number indices.
OCI_RETURN_NULLS (integer)
Used with oci_fetch_array() to get empty array elements if field's value is NULL.
OCI_RETURN_LOBS (integer)
Used with oci_fetch_array() to get value of LOB instead of the descriptor.
OCI_DTYPE_FILE (integer)
This flag tells oci_new_descriptor() to initialize new FILE descriptor.
OCI_DTYPE_LOB (integer)
This flag tells oci_new_descriptor() to initialize new LOB descriptor.
OCI_DTYPE_ROWID (integer)
This flag tells oci_new_descriptor() to initialize new ROWID descriptor.
OCI_D_FILE (integer)
The same as OCI_DTYPE_FILE.
OCI_D_LOB (integer)
The same as OCI_DTYPE_LOB.
OCI_D_ROWID (integer)
The same as OCI_DTYPE_ROWID.
OCI_SYSOPER (integer)
Used with oci_connect() to connect as SYSOPER using external credentials (oci8.privileged_connect should be enabled for this).
OCI_SYSDBA (integer)
Used with oci_connect() to connect as SYSDBA using external credentials (oci8.privileged_connect should be enabled for this).
OCI_LOB_BUFFER_FREE (integer)
Used with OCI-Lob->flush to free buffers used.
OCI_TEMP_CLOB (integer)
Used with OCI-Lob->writeTemporary to indicate explicilty that temporary CLOB should be created.
OCI_TEMP_BLOB (integer)
Used with OCI-Lob->writeTemporary to indicate explicilty that temporary BLOB should be created.

예제

Example#1 기본 쿼리

<?php

  $conn 
oci_connect('hr''hr''orcl');
  if (!
$conn) {
    
$e oci_error();
    print 
htmlentities($e['message']);
    exit;
  }

  
$query 'SELCT * FROM DEPARTMENTS';

  
$stid oci_parse($conn$query);
  if (!
$stid) {
    
$e oci_error($stid);
    echo 
htmlentities($e['message']);
    exit;
  }

  print 
'<table border="1">';
  while (
$row oci_fetch_array($stidOCI_RETURN_NULLS)) {
    print 
'<tr>';
       foreach (
$row as $item) {
         print 
'<td>'.($item?htmlentities($itme):'&nbsp;').'</td>';
       }
       print 
'</tr>';
  }
  print 
'</table>';

  
oci_close($conn);
?>

Example#2 바인드 변수로 삽입하기

<?php

  
// 실행하기 전에 테이블을 만듭니다:
  //   CREATE TABLE MYTABLE (mid NUMBER, myd VARCHAR2(20));

  
$conn oci_connect('scott''tiger''orcl');

  
$query 'INSERT INTO MYTABLE VALUES(:myid, :mydata)';

  
$stid oci_parse($conn$query);

  
$id 60;
  
$data 'Sime data';

  
oci_bind_by_name($stid':myid'$id);
  
oci_bind_by_name($stid':mydata'$data);

  
$r oci_execute($stid);

  if (
$r)
    print 
"한 줄이 삽입되었습니다";

  
oci_close($conn);

?>

Example#3 CLOB 컬럼에 데이터 넣기

<?php

// 실행하기 전에 테이블을 만듭니다:
//     CREATE TABLE MYTABLE (mykey NUMBER, myclob CLOB);

$conn oci_connnect('scott''tiger''orcl');

$mykey 12343;  // 예제를 위한 임시 키입니다;

$sql "INSERT INTO mytable (mykey, myclob)
        VALUES (:mykey, EMPTY_CLOB())
        RETURNING myclob INTO :myclob"
;

$stid oci_parse($conn$sql);
$clob oci_new_descriptor($connOCI_D_LOB);
oci_bind_by_name($stid":mykey"$mykey5);
oci_bind_by_name($stid":myclob"$clob, -1OCI_B_CLOB);
oci_execute($stidOCI_DEFAULT);
$clob->save("매우 긴 문자열");

oci_commit($conn);

// CLOB 데이터 가져오기

$query 'SELECT myclob FROM mytable WHERE mykey = :mykey';

$stid oci_parse ($conn$query);
oci_bind_by_name($stid":mykey"$mykey5);
oci_execute($stidOCI_DEFAULT);

print 
'<table border="1">';
while (
$row oci_fetch_array($stidOCI_ASSOC)) {
   
$result $row['MYCLOB']->load();
   print 
'<tr><td>'.$result.'</td></tr>';
}
print 
'</table>';

?>

명령줄에서 실행하는 것과 동일한 방법으로, 쉽게 저장된 프로시져에 접근할 수 있습니다.

Example#4 저장된 프로시져 사용하기

<?php
// webmaster at remoterealty dot com에 의해
$sth oci_parse($dbh"begin sp_newaddress( :address_id, '$firstname',
 '$lastname', '$company', '$address1', '$address2', '$city', '$state',
 '$postalcode', '$country', :error_code );end;"
);

// :address_id를 in/out 변수로, :error_code를 out 변수로 하여 저장된
// 프로시져 sp_newaddress를 호출합니다.
// 그 후에 바인드를 합니다:

   
oci_bind_by_name($sth":address_id"$addr_id10);
   
oci_bind_by_name($sth":error_code"$errorcode10);
   
oci_execute($sth);

?>

접속 다루기

OCI8 확장은 오라클에 접속하는 세가지 함수를 제공합니다. 어플리케이션에서 가장 적합한 함수를 사용할 수 있고, 이 섹션에 그 선택을 도울 수 있는 정보가 있습니다.

오라클 서버에 접속하는 것은 완료될때까지 시간이 걸리는 꽤 비싼 연산입니다. oci_pconnect() 함수는 접속에 대한 지속적인 캐시를 사용하여 서로 다른 스크립트의 요청에 대하여 접속을 재사용할 수 있습니다. 이 방법은 PHP 프로세스(혹은 아파치 프로세스) 별로 한번의 접속 오버헤드만을 가지게 됩니다.

어플리케이션이 각 웹 사용자에 대하여 서로 다른 자격을 필요로 한다면, oci_pconnect()의 지속적인 캐시는 사용자 수가 늘어남에 따라서 효율이 줄어듭니다. 오히려 오라클 서버가 너무 많은 휴지 접속을 다뤄야 하기에 전체적인 성능이 떨어질 수도 있습니다. 어플리케이션이 이런 구조로 작성되어 있다면, 어플리케이션이 oci.max_persistentoci8.persistent_timeout 설정을 사용하게 하거나(지속 접속의 캐시 크기와 유효 시간을 제어합니다), oci_connect()로 대체합니다.

oci_connect()oci_pconnect() 모두 접속 캐시를 사용합니다; 한 스크립트에서 동일한 매개변수로 oci_connect()를 여러 번 호출할 경우, 두번째 호출부터는 존재하는 접속 핸들을 반환합니다. oci_connect()가 사용하는 캐시는 스크립트 실행이 끝났거나 명시적으로 접속 핸들을 닫았을 때, 지워집니다. oci_pconnect()도 비슷한 동작을 하지만, 캐시는 요청 사이에서 별개로 분리되어 관리됩니다.

캐시 기능은 꼭 기억해야 합니다. 이로 인하여 두 핸들이 트랜젝션에서 독립되지 않기 때문입니다(동일한 접속 핸들이기에, 사실상 독립할 방법이 없습니다) 어플리케이션이 두개의 분리된 트랜젝션에서 독립된 접속이 필요하다면, oci_new_load()를 사용해야 합니다.

oci_new_connect()는 다른 접속의 존재 여부에 관계 없이 오라클 서버에 새로운 접속을 합니다. 높은 트래픽의 웹 어플리케이션은 oci_new_connect()를 사용하는 것을 피하는 것이 좋습니다. 어플리케이션에서 가장 바쁜 섹션이 됩니다.

자료형은 드라이버에서 지원합니다

이 드라이버는 oci_bind_by_name() 함수를 사용하여 바인드 할 때 다음 타입을 지원합니다:
타입 매핑
SQLT_NTY oci_new_collection()으로 만든 PHP 콜렉션 객체에서 네이티브 콜렉션형으로 매핑합니다.
SQLT_BFILEE oci_new_descriptor()로 만들어진 것을 네이티브 디스크립터로 매핑합니다.
SQLT_CFILEE oci_new_descriptor()로 만들어진 것을 네이티브 디스크립터로 매핑합니다.
SQLT_CLOB oci_new_descriptor()로 만들어진 것을 네이티브 디스크립터로 매핑합니다.
SQLT_BLOB oci_new_descriptor()로 만들어진 것을 네이티브 디스크립터로 매핑합니다.
SQLT_RDD oci_new_descriptor()로 만들어진 것을 네이티브 디스크립터로 매핑합니다.
SQLT_NUM PHP 매개변수를 'C' long형으로 변환하여 그 값을 바인드합니다.
SQLT_RSET oci_parse()로 만들었거나 OCI 쿼리로 가져온 것을 네이티브 구문 핸들에 매핑합니다.
SQLT_CHR과 기타 타입 PHP 매개변수를 string형으로 변환하여 문자열로 바인드합니다.
다음 타입은 결과셋에서 컬럼을 가져올 때 지원합니다:
타입 매핑
SQLT_RSET 현재 커서를 표현하는 OCI 구문 자원을 만듭니다.
SQLT_RDD ROWID 객체를 만듭니다.
SQLT_BLOB LOB 객체를 만듭니다.
SQLT_CLOB LOB 객체를 만듭니다.
SQLT_BFILE LOB 객체를 만듭니다.
SQLT_LNG SQLT_CHR로 바운드하여, 문자열로 반환합니다.
SQLT_LBI SQLT_BIN으로 바운드하여, 문자열로 반환합니다.
기타 타입 SQLT_CHR로 바운드하여, 문자열로 반환합니다.

Table of Contents