초간단 php-oracle 연동 클래스 | |||
| |||
뭔가 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 | |||
| |||
| |||
로그인을 하시면 댓글을 등록 할 수 있습니다. |
SIMILAR POSTS 오라클8i 글자수 무제한 게시판소스 |
OTHER POSTS IN THE SAME CATEGORY 폼메일 예제 |