초간단 php-oracle 연동 클래스

31367 
Created at 2006-11-24 03:50:09 
243   0   0   0  
PHP에서 오라클 연동하려면 좀 고통스럽다.

뭔가 mySQL이랑 좀 다른 부분도 있는것 같고..

하여 클래스로 만들어보았다.



class Oracle
{
  var $DBID = "id";
  var $DBPW = "pw";
  var $DBSID = "sid";

  var $conn;
  var $stmt;
        
  var $error = false;    // 에러 발생하면 true 로 수정됨. commit,rollback 결정에 사용
  var $transaction = false;    // true 면 auto commit 않함

  var $bind = array();
  var $data_size = array();

  // php4 의 생성자
  function Oracle(){    
            
    $this->connect();
  }
  // php5 의 생성자
  function __construct(){    
            
    $this->connect();
  }
  // php5 의 소멸자
  function __destruct(){    
            
    $this->disconnect();
  }

  function connect(){

    if(!$this->conn)
      $this->conn = OCILogon($this->DBID,$this->DBPW,$this->DBSID);
  }
        
  function disConnect(){

    if($this->stmt)
      @OCIFreeStatement($this->stmt);
    if($this->conn)
      @OCILogoff($this->conn);
  }
  // 바인드변수 값 지정
  // 같은 값이라도 executeDML() 호출전에 반드시 매번 호출해야 함(executeDML() 함수호출후 초기화되므로)
  function setBind($bind){

    if(is_array($bind))
      $this->bind = $bind;
    else if($bind)
      $this->bind = array($bind);
  }
  // 바인드변수 사이즈 지정. 지정안하면 해당변수의 최대사이즈가 기본값임
  function setDataSize($data_size){

    if(is_array($data_size))
      $this->data_size = $data_size;
    else if($data_size)
      $this->data_size = array($data_size);
  }
  // 쿼리문 결과를 '다중배열($rs[필드명][인덱스])'로 리턴한다
  // $preferch_size는 가져올 레코드건수를 지정함(옵션)
  function selectList($query,$preferch_size=1){
            
    $this->connect();
    $this->stmt = OCIparse($this->conn,$query);

    if($this->stmt){

      $this->bindByName();                                                        
      $this->prefetch($preferch_size);                                        

      if($this->transaction){                        
        @OCIexecute($this->stmt,OCI_DEFAULT);
        $this->error();
      }else{
        @OCIexecute($this->stmt);
      }
      $rows = @OCIFetchStatement($this->stmt,$rs);                
    
      if($rows){                    
        if(!$this->transaction)
          @OCIFreeStatement($this->stmt);
        return $rs;
      }
    }            
    return array();
  }
  // 쿼리문 결과 1건을 '배열($rs[필드명 or 인덱스])'로 리턴한다
  // $option 은 OCI_ASSOC(필드명) or OCI_NUM(인덱스) 을 지정(옵션)
  function selectRow($query,$option=OCI_ASSOC){
            
    $this->connect();
    $this->stmt = OCIparse($this->conn,$query);

    if($this->stmt){

      $this->bindByName();

      if($this->transaction){                        
        @OCIexecute($this->stmt,OCI_DEFAULT);
        $this->error();
      }else{
        @OCIexecute($this->stmt);
      }
      if(@OCIFetchInto($this->stmt,$rs,$option+OCI_RETURN_NULLS)){
        if(!$this->transaction)
          @OCIFreeStatement($this->stmt);
        return $rs;
      }                    
    }            
    return array();
  }
  // 한개 값만 리턴하는 쿼리문을 처리한다
  // ROWID,LOB,FILE 등 외에는 스트링으로 반환한다
  function selectOne($query){

    $this->connect();
    $this->stmt = OCIparse($this->conn,$query);        

    if($this->stmt){

      $this->bindByName();

      if($this->transaction){                        
        @OCIexecute($this->stmt,OCI_DEFAULT);
        $this->error();
      }else{
        @OCIexecute($this->stmt);
      }
      if(@OCIFetch($this->stmt)){

        // 인수 1은 컬럼순서 인덱스(1부터 시작함에 주의!,컬럼명 지정도 가능)
        $value = @OCIResult($this->stmt,1);    
        if(!$this->transaction)
          @OCIFreeStatement($this->stmt);
        return $value;
      }
    }
  }
  // insert,update,delete등을 실행후 영향받은 로우의 갯수를 리턴한다(auto commit일 경우만 갯수를 리턴함)
  // $transaction=true 일 경우 마지막에 반드시 commit() 함수를 호출한다
  function executeDML($sql){

    $this->connect();
    $this->stmt = OCIparse($this->conn,$sql);    
            
    if($this->stmt){

      $this->bindByName();

      if($this->transaction){    // auto commit 이 아닐 경우
        @OCIexecute($this->stmt,OCI_DEFAULT);
        $this->error();
      }else{
        @OCIexecute($this->stmt);
        $num = @OCIRowCount($this->stmt);
        @OCIFreeStatement($this->stmt);
                    
        return $num;                    
      }
    }
  }
  // auto commit 않하고 명시적으로 transaction 시작
  // executeDML() 호출후 마지막에 반드시 commit() 함수를 호출한다
  function transaction(){

    $this->transaction = true;
  }
  // transaction 완료후 commit 이면 true를 리턴함
  // executeDML() 에서 에러가 하나라도 발생하면 자동 rollback 됨
  function commit(){

    if(!$this->error){
      @OCICommit($this->conn);
      $commit = true;
    }else{
      @OCIRollback($this->conn);
      $commit = false;
    }
    if($this->stmt)
      @OCIFreeStatement($this->stmt);

    $this->transaction = false;
    $this->error = false;

    return $commit;
  }
  // $transaction=true 일 경우 매번 executeDML 에서 자동호출된다
  // 에러 발생할 경우 commit,rollback의 판단기준인 $error 값을 변경
  function error(){

    if($error = @OCIError($this->stmt)){                
      //echo "<p> Error is : " . $error["code"] . " - " . $error["message"] . "<p>";
      $this->error = true;
    }
  }
  // :b1,:b2,:b3...에 바인드 변수 지정
  // 바인드변수명은 반드시 :b1,:b2,:b3... 으로 지정한다
  function bindByName(){

    $size = sizeof($this->bind);

    for($i=0 ; $i < $size ; $i++){

      $ds = $this->data_size[$i];
      if(!$ds) $ds = -1;

      @OCIBindByName($this->stmt,":b".($i+1),$this->bind[$i],$ds);
    }
    $this->bind = array();                                                        
    $this->data_size = array();
  }
  // 오라클 클라이언트 버퍼에 저장되는 레코드의 수를 지정
  // 여러 레코드를 select할 경우 디폴트 값이 작아서 비효율적이면 가져올 건수만큼 지정
  function prefetch($preferch_size){

    if($preferch_size > 1)
      @OCISetPrefetch($this->stmt,$preferch_size);
  }
}

################# 여기서부터 사용예 입니다 #################

1. 여러건의 레코드를 select 할 경우
$db = new Oracle();
$query = "select title,name,date from tb where ... 생략";
$rs = $db->selectList($query);
for( $i=0 ; $i < sizeof($rs["TITLE"]) ; $i++ ){
    echo $rs["TITLE"][$i] . $rs["NAME"][$i] . $rs["DATE"][$i] . "<br>";
}
* 주의하실건 꼭 배열에 대문자로 적으셔야 한다는 겁니다

2. 한건의 레코드를 select 할 경우
$query = "select title,name,date from tb where rownum=1";
$rs = $db->selectRow($query);
echo $rs["TITLE"] . $rs["NAME"] . $rs["DATE"];

3. 한개값을  select 할 경우
$query = "select count(*) from tb";
$value = $db->selectOne($query);
echo "총 " . $value . " 건 입니다";

4. insert,update,delete 할 경우
$sql = "insert into tb (title,name) values ('$title','$name')";
$rs = $db->executeDML($sql);
if($rs){
 echo $rs . " 건의 데이터를 처리하였습니다";
}    

5. 트랜젝션 처리
$sql1 = "insert into tb1 ... 생략";
$sql2 = "insert into tb2 ... 생략";
$sql3 = "insert into tb3 ... 생략";
$db->transaction();
$db->executeDML($sql1);
$db->executeDML($sql2);
$db->executeDML($sql3);
$rs = $db->commit();
if($rs){
  echo "처리 성공!";
}else{
  echo "에러 발생!";
}
transaction() 함수를 호출하면 auto commit 이 false 가 되며 마지막에 commit() 함수를 호출하면 에러가 하나라도 발생하면 자동으로 롤백됩니다 물론 에러가 없으면 커밋되구요 함수명이 commit 이라고 무조건 커밋되는거 아닙니다 ^^
transaction() 함수를 호출않하고 executeDML()을 사용하면 항상 auto commit 입니다

6. 바인드변수 사용
$query = "select name from tb where id=:b1 and pw=:b2";
$bind = array($id,$pw);
$db->setBind($bind);
$name = $db->selectOne($query);
echo $name;

바인드 변수명은 꼭 :b1,:b2,:b3... 이런식으로 지정하며 setBind() 함수에 배열로 값을 넘겨줍니다
바인드변수가 :b1 한개만 사용된 경우는 배열이 아니라 값하나만 넘겨도 됩니다(아래예 처럼)
넘겨진 값은 selectXxx(),executeDML()등의 함수사용후에 초기화되므로 함수 실행전에 매번 setBind() 함수를 호출해야 합니다
아래예는 틀린 사용예입니다 $cnt2 에는 아무값도 없습니다
$query1 = "select count(*) from tb1 where id=:b1";
$query2 = "select count(*) from tb2 where id=:b1";
$db->setBind($id);
$cnt1 = $db->selectOne($query1);
$cnt2 = $db->selectOne($query2);

아래예가 옳은 사용예입니다
$db->setBind($id);
$cnt1 = $db->selectOne($query1);
$db->setBind($id);
$cnt2 = $db->selectOne($query2);

7. 트랜젝션 처리와 바인드 변수 사용
$sql1 = "insert into tb(title,name) values(:b1,:b2)";
$sql2 = "update tb2 set addr=:b1 where id=:b2";
$bind1 = array($title,$name);
$bind2 = array($addr,$id);
$db->transaction();
$db->setBind($bind1);
$db->executeDML($sql1);
$db->setBind($bind2);
$db->executeDML($sql2);
$rs = $db->commit();
if($rs){
  echo "처리 성공!";
}else{
  echo "에러 발생!";
}

Tags: oracle Share on Facebook Share on X

◀ PREVIOUS
금액을 입력할때 세자리마다 컴마찍기
▶ NEXT
http-2.2.3에서 ssl 설치
  댓글 0
로그인을 하시면 댓글을 등록 할 수 있습니다.
SIMILAR POSTS

오라클8i 글자수 무제한 게시판소스 (created at 2006-12-22)


OTHER POSTS IN THE SAME CATEGORY

폼메일 예제 (created at 2006-12-22)

include 집중해부 (created at 2006-12-22)

한글 처리 (created at 2006-12-22)

브라우져 캐시(cache) 안먹게 하는 비기 (created at 2006-12-22)

csv 파일을 이용한 메일링 리스트 구현 (created at 2006-12-22)

오라클8i 글자수 무제한 게시판소스 (created at 2006-12-22)

동적 이미지(실시간 그래프) 생성하기 (created at 2006-12-22)

UTF-8로 파일 저장하기 (created at 2006-12-22)

발신전용 메일서버 만드는 방법 (created at 2006-12-21)

구글 검색시 순위 올리기 (created at 2006-12-18)

사이트 트래픽의 주범 웹봇 차단하기 - robots.txt (created at 2006-12-18)

Internet Explorer의 검색창에서 한글 입력이 안될때 (created at 2006-11-24)

프린터 인쇄 취소가 안될때 (created at 2006-11-24)

spoolsv.exe의 문제 cpu점유률 100% (created at 2006-11-24)

http-2.2.3에서 ssl 설치 (created at 2006-11-24)

금액을 입력할때 세자리마다 컴마찍기 (created at 2006-11-24)

쿠키 세팅하기 (created at 2006-11-22)

초간단 AJAX 샘플 (created at 2006-11-22)

Hello World 뿌리기 (created at 2006-11-18)

텍스트 인쇄하기 (created at 2006-11-17)

Region을 이용한 부정형 윈도 만들기 (created at 2006-11-16)

유동 IP로 DNS 매핑하여 서비스 하는 방법 (created at 2006-10-14)

MS IE7.0 가세「툴바 전쟁」혈투 예고 (created at 2006-10-14)

어떤 프로세스가 메모리를 가장 많이 차지하는지 알아보는 방법? (created at 2006-10-13)

어떤 디렉토리가 가장 큰지 알아내는 방법? (created at 2006-10-13)

root password 까먹었을때? (created at 2006-10-13)

지정날짜에 이미지 보여주기 혹은 감추기 (created at 2006-10-10)

구글 메일(GMail)로 메일 발송하기 (created at 2006-10-10)

window 스스로 닫기 (created at 2006-10-10)

이미지를 지정된 비율로 자르기 (crop) (created at 2006-10-10)

UPDATES

자리 마음에 안든다고 6급 공무원 패는 농협 조합장 (created at 2024-03-26)

85세 딸 짜장면 사주는 102세 어머니 (created at 2024-03-26)

1990년대 감각파 도둑 (created at 2024-03-26)

치매에 걸린 69살의 브루스 윌리스가 전부인 데미무어를 보고 한 말 (updated at 2024-03-22)

일제강점기가 더 살기 좋았을지도 모른다는 조수연 국민의힘 후보 - 친일파? (updated at 2024-03-14)

성일종 인재육성 강조하며 이토 히로부미 언급 - 인재 키운 선례? (updated at 2024-03-13)

경제는 대통령이 살리는 것이 아닙니다 라던 윤석열대통령 - 상황 안좋아지자 여러 전략을 펼쳤지만, 부작용 속출했던 2024년의 봄 (updated at 2024-03-13)

극빈의 생활을 하고 배운것이 없는 사람은 자유가 뭔지도 모를 뿐 아니라 왜 개인에게 필요한지에 대한 필요성을 못느낀다는 윤석열 대통령 (updated at 2024-03-08)

조선일보를 안본다는 사람들이 말하는 그 이유 - 천황폐하, 전두환 각하, 김일성 장군 만세? (created at 2024-03-07)

광폭타이어를 장착하면 성능이 좋아질거라는 착각 (updated at 2024-03-03)

면허시험장에서 면허갱신하면 하루만에 끝나나? (updated at 2024-03-03)

신한은행/신한투자증권 금융거래 종합보고서 다운로드 방법 (updated at 2024-02-26)

100년 된 일본 장난감 회사가 내놓은 변신 기술에 난리난 과학계 (created at 2024-02-26)

알리에서 발견한 한글 지원하는 가성비 쩌는 무선 기계식키보드 (updated at 2024-02-25)

쌍팔년도가 1988년인줄 알았던 1인 (updated at 2024-02-23)

이쁜 색으로 변신한 테슬라 사이버트럭 (created at 2024-02-23)

2024년 카타르 아시안컵 4강전 전날 한국 대표팀 내부에 있었던 이강인의 폭주 (updated at 2024-02-21)

강릉 맛집 지도 (updated at 2024-02-20)

간이 안좋을 때 나타나는 증상 20가지 (updated at 2024-02-20)

배설물을 이용하여 일본에 저항했던 독립운동가 조명하 (updated at 2024-02-20)

요건 몰랐지롱? 이순신을 사랑한 외국인 (created at 2024-02-20)

원빈도 머리빨 (created at 2024-02-19)

대표적인 대한민국의 미남배우 중 하나인 원빈 (created at 2024-02-19)

백제의 건국 시조 온조왕 (updated at 2024-02-19)

700년동안 대한민국 고대국가의 한축이었던 백제시대 (created at 2024-02-19)

대머리들에게 주는 대머리의 조언 (created at 2024-02-17)

일본의 여성 락그룹 프린세스 프린세스의 "다이아몬드" (created at 2024-02-17)

결혼식 직전 연락두절된 신랑 (created at 2024-02-17)

대한민국 축구팀 파문으로 인해 중국 소셜미디어까지 등장한 탁구 전도사 이강인 (updated at 2024-02-16)

조국의 반격으로 흥미진진하게 흘러가는 한국의 정치판 - 데뷰와 동시에 한동훈 장관에게 던진 4개의 질문 (updated at 2024-02-15)

2024년 카타르 아시안컵 4강전 전날 내분사태로 갑자기 회자되는 이승우선수의 친화력 (created at 2024-02-15)

카카오뱅크 금융거래종합보고서/잔액증명서/거래내역서 발급 방법 (created at 2024-02-14)

아이가 최고의 스승이었다 (created at 2024-02-13)

이제는 국민 유행어로 등극한 한동훈의 "싫으면 시집가" (updated at 2024-02-13)

설 연휴 잔소리 메뉴판 - 이제 잔소리 하기전에 요금부터... (updated at 2024-02-10)

로버트 드니로의 70년 전 모습 (created at 2024-02-08)

카메라 어플로 만들어본 슈퍼걸 - 엄... 최종 작품은 왠지... (created at 2024-02-08)

앞트임 하고 새롭게 태어난 대한민국의 젊은 용사 (created at 2024-02-08)

비가 억수로 내리던 2024년의 2월 어느날 캘리포니아의 밤 카니예 웨스트와 그의 아나 비앙카 센소리 (updated at 2024-02-08)

스케방형사 1화 - 수수께끼의 전학소녀사키 (created at 2024-02-05)

백제와 일본의 교류가 가장 활발했던 시기는 근초고왕 시대 (created at 2024-02-05)

일에 찌들은 아빠가 꿈에서 깨어나지 않자 구출해주는 짱구 (created at 2024-02-03)

이제는 할아버지가 된 휴 그랜트(Hugh Grant)가 블랙핑크 콘서트에 다녀온 후 소감 (created at 2024-02-03)

다시 한번 감상해보는 추억의 날리면 패러디 (updated at 2024-02-01)

25년간 노예로 살다가 돌아온 남동생 (created at 2024-02-01)

가까우면서도 멀게 느껴지는 나라 일본 (created at 2024-02-01)

친구와 비교하다가 이혼하게 된 부부 (created at 2024-02-01)

요꼬 미나미노의 바람의 마도리걸(風のマドリガル) (created at 2024-01-30)

옛날 어린이들이 신문을 챙겨봤던 이유 (created at 2024-01-30)

Remaster된 요꼬 미나미노(南野陽子)의 판도라의 연인(パンドラの恋人) (updated at 2024-01-30)