2015-10-15
컬럼이 모두 NOT NULL로 되어 있는 테이블에 임의의 한 ROW를 INSERT 시키려고 할때, 해당 컬럼들에 기본값 설정이 안되어 있는 상태라면.. 해당 컬럼에 맞는 기본 값들을 일일이 넣어주어야 한다.
그냥 INSERT를 할경우 해당 컬럼에 맞는 기본값을 넣어주라는 오류가 뜰것이기 때문이다.

그래서 만들어 봤다.
information_schema에서 해당 테이블의 정보를 가져와서 알아서 기본값을 넣어주는 소스이다.
insert_default( $table_name )
{
    $get_table_info = "
        SELECT 
            *
        FROM
            `information_schema`.`COLUMNS`
        WHERE 
            `TABLE_NAME` = :table
            AND 
            `TABLE_SCHEMA` = 'aaa'
    ";

    $get_auto_increment = "
        SELECT 
            `AUTO_INCREMENT` as ai
        FROM 
            `information_schema`.`TABLES`
        WHERE 
            `TABLE_NAME` = :table
            AND 
            `TABLE_SCHEMA` = 'aaa'
    ";

    //위의 2가지 쿼리를 실행시켜주는 부분으로, 이부분은 각자 환경에 맞는 함수로 대체해줘야 할것이다.
    $info_result = $this->_q( $get_table_info, array('table'=>$table_name) );
    $auto_inc = $this->_q( $get_auto_increment, array('table'=>$table_name), array('fetch') );

    $insert_query = "INSERT INTO ".$table_name." SET ";
    $insert_col = '';
    foreach( $info_result as $tv )
    {
        if( $tv['EXTRA'] == 'auto_increment' ) 
        {
            $insert_col .= '`'.$tv['COLUMN_NAME']."` = '".$auto_inc['ai']."' ";
        }
        else if( preg_match('/BIT|TINYINT|SMALLINT|MEDIUMINT|INT|INTEGER|BIGINT|DECIMAL|DEC|NUMERIC|FIXED|FLOAT|DOUBLE|REAL|FLOAT|BOOL|BOOLEAN/i', $tv['DATA_TYPE']) )
        {
            $insert_col .= ',`'.$tv['COLUMN_NAME']."` = 0 ";
        }
        else if( preg_match('/DATE|DATETIME|TIME|YEAR|TIMESTAMP/i', $tv['DATA_TYPE']) )
        {
            $insert_col .= ',`'.$tv['COLUMN_NAME']."` = now() ";
        }
        else
        {
            $insert_col .= ',`'.$tv['COLUMN_NAME']."` = '' ";
        }
    }

    if( substr($insert_col, 0, 1) == ',' ) $insert_col = substr($insert_col, 1);

    return $insert_query.$insert_col;
}
보면 알겠지만, 컬럼들의 DATATYPE을 조사하여 숫자들은 0을 DATE타입에는 NOW()를 나머지엔 공백을 넣어준 채로 INSERT구문을 완성해 주는 소스이다.
거기다가 auto_increment는 특별히 해당 값을 가져와서 넣어주도록 해놓았다.

필자는 개인적으로 만들어진 쿼리 함수를 쓰기 때문에, 위 소스에서 쿼리를 실행시켜서 값을 가져오는 부분은 사용하는 환경에 맞게 바꿔 놓아야 할 것이다.