제목 | oci8 driver 버그.. | ||
---|---|---|---|
글쓴이 | jyp | 작성시각 | 2013/08/29 19:39:31 |
|
|||
이전까지는 CI에서 mysql만 사용하다가 얼마전에 오라클을 처음으로 연동해서 사용해 봤는데요 다른부분은 문제가 없었는데 오라클에서 sequence number를 가져오는 쿼리를 실행하면 sequence number가 항상 +2가 되어서 리턴되더라구요. 그래서 CI코드를 봤는데 완전 코어단 까지는 잘 모르겠고 DB_driver.php 파일의 query() 함수에서 기본적으로 // Run the Query
if (FALSE === ($this->result_id = $this->simple_query($sql)))
{
에서 simple_query()를 호출하여 먼저 쿼리를 한번 날리고
function simple_query($sql)
{
if ( ! $this->conn_id)
{
$this->initialize();
}
return $this->_execute($sql);
}
여기서 _execute() 부분이 실제 쿼리를 날리는 부분 같습니다. 암튼 여기서 쿼리가 한번 실행되면 $this 객체의 result_id, stmt_id 에 모두 값이 세팅 되더군요. 그런데 문제는 $driver = $this->load_rdriver();
$RES = new $driver();
$RES->conn_id = $this->conn_id;
$RES->result_id = $this->result_id;
if ($this->dbdriver == 'oci8')
{
$RES->stmt_id = $this->stmt_id;
$RES->curs_id = NULL;
$RES->limit_used = $this->limit_used;
$this->stmt_id = FALSE;
}
위 코드와 같이 oci8드라이버를 사용할 경우 $RES객체에 simple_query()로 받아온 결과를 그대로 세팅을 하는데 바로 아래에서 $RES->num_rows = $RES->num_rows(); 위와 같은 코드가 한번 더 싱행이 되더군요... 이 num_rows()라는 함수는 drivers/oci8/oci8_result.php 여기에 있는 함수로 public function num_rows()
{
if ($this->num_rows === 0 && count($this->result_array()) > 0)
{
$this->num_rows = count($this->result_array());
@oci_execute($this->stmt_id);
if ($this->curs_id)
{
@oci_execute($this->curs_id);
}
}
return $this->num_rows;
}
그래서 기존의 코드를 주석 처리 하고위와 같은 기능을 하더라구요.... 이전 코드에서 $RES객체에 따로 num_rows를 세팅하지 않았고, 이미 simple_query() 함수를 통해서 result를 받아온 상황이라 첫번째 if문에서 바로 걸리게 되죠. 그래서 if문으로 들어와서 @oci_execute($this->stmt_id); 를 실행하는데 이때 쿼리를 한번 더 날리는것 같습니다. 그래서 sequence_number가 항상 +2가 됐던것 같구요.. //$RES->num_rows = $RES->num_rows();
$RES->result_array();
$RES->num_rows = count($RES->result_array);
이렇게 수정 했습니다. $RES->result_array(); 이 함수를 호출하는 이유는 simple_query() 함수를 호출했을때 $RES의 result_array 프로퍼티에 실제 결과값이 저장되는게 아니라 객체(?)로 결과값을 가지고 있어서 저 함수를 실행해야 result_array 프로퍼티에 값이 세팅 되더군요.. 그래서 핵심은
simple_query()로 한번 결과를 가져오고, 하지만 result_array()에는 결과가 실제로 저장돼있지는 않음 result_array 프로퍼티에 결과저장 및 row_num 을 구하기 위해 row_nums() 함수를 호출 여기서 @oci_execute() 함수로 한번더 DB로 쿼리를 날림 이게 문제였던것 같습니다 |
|||
다음글 | 화면이 작아서 고생하시는 분들 (3) | ||
이전글 | helper에서 세션 객체 접근 (2) | ||
들국화
/
2013/08/30 11:53:05 /
추천
0
|
jyp
/
2013/08/30 11:57:35 /
추천
0
$this->db->query(); 로 바로 쿼리를 날립니다. insert를 하는건 없네요
sequence number가 항상 +2로 리턴이 된다는것은 실제로 oracle에 쿼리가 두번 날라갔다는 의미 아닌가요? curval을 가져올때 마다 자동으로 +1이 되니까요 |
들국화
/
2013/08/30 12:09:10 /
추천
0
jyp/ 실제 쿼리 문이 궁금 하네요.
INSERT INTO MYTABLE VALUES( SEQ_ID.NEXTVAL, '홍길동');이런 형태로 넣는거 아닌가요? curval 은 몇번을 하던 +1이 안되는거 아닌가요? 머 어쨌든 버그가의심되면 버그래포팅 해서 한국개발자도 CI발전에 동참을.. ^^ |
jyp
/
2013/08/30 12:12:37 /
추천
0
아 네 nextval 입니다 ㅎㅎ
|
stmt_id 이게 뭔지 모르겠네요... Statement ID 즉 쿼리문 ID 인듯 한데..
인서트 문에 쿼리를 포함해서 넣은 건가요?오라클 써본지 워낙에 오래 돼서 기억이 가물 가물 한데... 시퀀스 넘버를 구해와서 인서트를 해서 그런건 아닌가요?
버그가 맞다면 버그레포팅 해주세요. ^^;
검색하다 보니 오라클 관련해 알려진 버그가 있네요. 심각한 버그네요. ㅎㅎㅎ
https://github.com/EllisLab/CodeIgniter/wiki/Oracle:Known-Issues