제목 | sqlsrv_forge.php의 _alter_table 버그 | ||
---|---|---|---|
글쓴이 | 오봉구 | 작성시각 | 2013/10/19 01:10:42 |
|
|||
CI 2.1.4 를 사용중입니다 db drvier는 sqlsrv를 사용중이구요, add_column() 함수를 사용했는데요, 사용자 가이드와 달리 에러를 뱉어내더라구요, core를 찾다보니 버그인것 같아 글을 남깁니다. 사용자 가이드에 보면 $fields = array( 'preferences' => array('type' => 'TEXT') ); $this->dbforge->add_column('table_name', $fields); 와 같이 사용하는 함수입니다. 두번째 파라미터에서 배열의 형식으로 값을 넘겨줍니다. 실제로 system/database/DB_forge.php를 열어서 252번째 줄을 열어보면 function add_column($table = '', $field = array(), $after_field = '') 파라미터가 배열형식으로 넘어가는 것을 확인 할 수 있습니다. add_column() 함수 내부에 $this->_alter_table() 함수를 통해 각 db driver의 함수가 실행되게 되는데, mysql driver의 경우에는 _protect_identifiers() 란 함수를 통해 파라미터로 넘겨준 배열을 스트링으로 만들어주는 과정을 거쳐 정상적으로 동작하게 되는데, sqlsrv driver의 경우에는 이러한 과정없이 array를 바로 쿼리문에 집어넣게 됩니다. 그래서 생성된 쿼리를 보면 ~~~ 컬럼명 컬럼속성(컬럼길이) ~~~~ 와 같이 생성되어야 할 쿼리가 ~~~ Array ~~~ 와 같이 생성되어서 에러가 나더라구요, 위 문제를 해결하려면 system/database/drivers/sqlsrv_forge.php 의 191번째 줄에 있는 _alter_table() 함수를 수정하시면 됩니다. 원래 코드는 function _alter_table($alter_type, $table, $column_name, $column_definiti $default_value = '', $null = '', $after_field = '')
{
$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);
// DROP has everything it needs now.
if ($alter_type == 'DROP')
{
return $sql;
}
$sql .= " $column_definition";
제가 수정한 코드는 function _alter_table($alter_type, $table, $column_name, $column_definiti $default_value = '', $null = '', $after_field = '')
{
$field_name = array_keys($column_name)[0];
$column_definition = $column_name[$field_name];
$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($field_name);
// DROP has everything it needs now.
if ($alter_type == 'DROP')
{
return $sql;
}
//$sql .= " $column_definition";
if (array_key_exists('type', $column_definition)) {
$sql .= " ".$column_definition['type'];
if (array_key_exists('constraint', $column_definition)) {
$sql .= "(".$column_definition["constraint"].")";
}
}
|
|||
다음글 | layout을 사용할때 view안에 css넣기 (1) | ||
이전글 | Controller를 통한 전역변수 사용 (3) | ||
letsgolee
/
2013/10/19 20:34:08 /
추천
0
|
한대승(불의회상)
/
2013/10/21 08:53:56 /
추천
0
오봉구// 좋은 정보 감사 합니다.
주로 사용되는 DB가 mysql이다 보니 다른 DB에 대한 버그들은 잘 인지 하지 못하게 되는군요. 소중한 정보 다시 한번 감사 합니다. |
소스를 더 살펴보니 mysql 의 경우 _process_fields란 함수를 이용해서 여러 column값을 스트링으로 전환을 합니다. 그런데 이 함수가 sqlsrv에서는 제공이 안되어 있습니다. 따라서 mysql에서처럼 배열로 주어진 여러개의 컬럼 정보들을 스트링으로 변환하는 _process_fields함수를 따로 만들어 사용해야 할 것 같네요. mysql의 함수를 조금 수정하면 될 것 같습니다. 마찬가지로 _alter_table함수도 mysql의 함수를 참조해 수정하면 될 것 같구요.
이 문제는 3.0버젼에서 해결될 것처럼 보입니다. 소스 구조가 전체적으로 바뀌어 관련 _process_column함수가 존재합니다. 오봉구님은 버그 캐처같습니다. 아래에서도 where_in버그도 찾으시더니...