디비 테이블 key 존재여부 확인후 쿼리 실행

디비 테이블 key 존재여부 확인후 쿼리 실행

QA

디비 테이블 key 존재여부 확인후 쿼리 실행

본문

sql_query(" ALTER TABLE `g5_point` ADD KEY `index2` (`po_expire_date`); ", true);

 

위 쿼리를 실행해서 디비 g5_point 테이블에 해당 key 값이 존재하면 false 하고

없으면 실행하려고 합니다.

 

구글링해서 찾아서 만든 문법이 아래와 같은데, 정상적으로 작동하지 않아서 냑 님들의 조언 부탁합니다

 

if(!sql_query(" SELECT po_expire_date FROM Information_schema.table_constraints WHERE table_schema=디비테이블 AND table_name=`{$g5['point_table']}` ", false)) {
    sql_query(" ALTER TABLE `{$g5['point_table']}` ADD KEY `index2` (`po_expire_date`); ", true);
}

 

또는

 

if(!sql_query(" SELECT po_expire_date FROM Information_schema.table_constraints WHERE table_name=`{$g5['point_table']}` ", false)) {
    sql_query(" ALTER TABLE `{$g5['point_table']}` ADD KEY `index2` (`po_expire_date`); ", true);
}

이 질문에 댓글 쓰기 :

답변 3

SHOW INDEX FROM g5_write_faq; 
문장으로 해당 테이블에 걸린 인덱스를 확인해 보셔야 할 것 같습니다.

참고로 인덱스 명은 컬럼명에 관계 있게 명명하겠지만
이미 다른 인덱스가 두개 이상의 컬럼을 걸어서 사용할 경우도 있다는 부분을 참고하여 명명하셔야 할 것 같습니다.

아래의 에러는 글자 그대로 해당 테이블에 이미 wr_seo_title 라는 이름의 인덱스"명" (인덱스 컬럼이 아닌) 이 있다는 의미 입니다.
이미 있는 인덱스 "명"을 사용해서 인덱스를 생성하려 한 상황인듯 보입니다.

-----------
요녀석은 아래와 같이 에러를 토해내는군요 ㅠㅠ
ALTER TABLE `g5_write_faq` ADD KEY `wr_seo_title` (`wr_seo_title`)
1061 : Duplicate key name 'wr_seo_title'

그누보드 자료를 찾아보니 이렇게 구현했군요

$row2 = sql_fetch(" SHOW COLUMNS FROM `g5_write_free` LIKE 'wr_seo_title' ");
if( !$row2 ){
  sql_query("ALTER TABLE `g5_write_free`
      ADD `wr_seo_title` varchar(200) NOT NULL DEFAULT '' AFTER `wr_content`,
      ADD INDEX `wr_seo_title` (`wr_seo_title`);
    ", false);
    $is_check = true;
}

참고자료 : gnuboard_patch5.4.1.patch.tar.gz > dbupgrade.php
https://sir.kr/g5_pds/4925


<?
$sql = "SELECT po_expire_date FROM Information_schema.table_constraints WHERE table_schema=디비테이블 AND table_name=`{$g5['point_table']}`";
$result = sql_query($sql);
$row = sql_fetch_array($result);
if($row['po_expire_date'] == ""){
  sql_query(" ALTER TABLE `{$g5['point_table']}` ADD KEY `index2` (`po_expire_date`); ");
}
?>

이렇게 하면 될 것 같은데 우선

SELECT po_expire_date FROM Information_schema.table_constraints WHERE table_schema=디비테이블 AND table_name=`{$g5['point_table']}` 이 문장이 정상적으로 실행되는지 먼저 mysql에서 확인 하는 것이 좋을 것 같습니다.

 

 

g5_point 테이블은 무사히 통과가 되었습니다

$sql_key = "SELECT wr_seo_title FROM Information_schema.table_constraints WHERE table_schema=`디비네임` AND table_name=`g5_write_free`";
echo $sql_key."<br>";
$qry_key = sql_query($sql_key);
$row_key = sql_fetch_array($qry_key);
if($row_key['wr_seo_title'] == ""){
sql_query(" ALTER TABLE `g5_write_free` ADD KEY `wr_seo_title` (`wr_seo_title`) ", true);
}

요녀석은 아래와 같이 에러를 토해내는군요 ㅠㅠ
ALTER TABLE `g5_write_faq` ADD KEY `wr_seo_title` (`wr_seo_title`)
1061 : Duplicate key name 'wr_seo_title'

답변을 정리하는 동안 어찌 해결 하셨나 봅니다. ^^

제가 사용하던 소스 일부를 정리해서 올립니다.

Library File
-------------

/*
Table 의 특정 컬럼에 걸린 인덱스의 여부를 확인함
다중 컬럼에 인덱스가 걸린 경우에도 True
Index Drop 시에는 컬럼별로 검사하지 않고 특정 이름만을 삭제 함
- DBA가 개별로 인덱스를 만들어 둘 수 있기 때문에 그냥 둠.
- 적정히 사용하지 않으면 인덱스를 프로그램에서 계속 만드는 위험이 있으므로 삭제 상태를 꼭 확인해 봐야 함.
*/
function hDB_findColIndex ($agTable, $agIndex)
{
    $rtFind = false;
    
    $lSql = "SHOW INDEX FROM `{$agTable}` WHERE Column_name = '{$agIndex}'";
    $lRow = sql_fetch($lSql);
    if ($lRow)
    {
        $rtFind = true;
    }
    return $rtFind;
}

//function hDB_createIndexCol ($agTable, $agIndexName, $agIndexs, ...)
function hDB_createIndexCol ()
{
    $args = func_get_args();
    $argc = func_num_args();
    // 최소한 테이블명, 인덱스명, 인덱스용 컬럼 1개 이상 : 총 3개 이상
    if ($argc < 3) return False;
    
    $agTable = $args[0];
    $agIndexName = $args[1];
    
    // 세번째 이후 인덱스를 모두 카피
    $agIndexs = array();
    for ($i = 2; $i < $argc; $i++) {
        $agIndexs[$i-2] = $args[$i];
    }
    
    $lSql = "";
    $lSql .= "CREATE INDEX `{$agIndexName}` ON `{$agTable}` ( ";
    $lSql .=  "`" . implode( "`, `", $agIndexs ) . "`" ;
    $lSql .= " ) USING BTREE";
    // 에러 처리용 : sql_query($lSql, True);
    // $rtVal == False 이면 mysql_error, mysqli_error 등으로 에러메세지 확인
    $rtVal = False;
    $rtVal = sql_query($lSql, False);
    
    return $rtVal;
}
// $Colume이 걸린 인덱스를 찾아서 삭제 하지 않음 (수동으로 만든 경우가 있으므로)
// 지정한 이름 (본 루틴에서 생성한) 의 인덱스만 삭제 함
function hDB_dropIndexName ($agTable, $agIndexName)
{
    $lSql = "";
    $lSql .= "DROP INDEX `{$agIndexName}` ON `{$agTable}`"; 
    
    // 에러 처리용 : sql_query($lSql, True);
    // $rtVal == False 이면 mysql_error, mysqli_error 등으로 에러메세지 확인
    $rtVal = False;
    $rtVal = sql_query($lSql, False);
    return $rtVal;
}
/* Test SQL
SHOW INDEX FROM g5_write_f_plaza01
SHOW INDEX FROM g5_write_f_plaza01 WHERE Column_name == 'wr_last'
CREATE INDEX 인덱스이름 ON 테이블이름 (필드이름1, 필드이름2, ...) 
CREATE INDEX `hI_g5_write_f_plaza01_wr_last` ON `g5_write_f_plaza01` (`wr_last`) USING BTREE; 
DROP INDEX `hI_g5_write_f_plaza01_wr_last` ON `g5_write_f_plaza01`; 
*/

=================================================
실제 사용 예
-------------

if ($lBoset['db_index_gen'] === 'T') {
    
    //---------
    // 최근일로 볼 때가 많은데 이 경우 인덱스가 없어서 DB 속도 저하를 초래 함.
    // 자동으로 인덱스를 생성
    $lIndexCol = 'wr_last';
    // 최근 일로 볼때 인덱스 자동 생성 및 보지 않을때 인덱스 삭제
    $lWriteTable = $g5['write_prefix'] . $bo_table; // 게시판 테이블 전체이름
    $lWriteTable_IndexName = "hI_{$lWriteTable}_{$lIndexCol}";
    $flagWrIndex = False;
    $flagWrIndex = hDB_findColIndex ($lWriteTable, $lIndexCol);
    if(stripos($bo_sort_field, $lIndexCol) !== false) {
        // wr_last 로 세팅 , 인덱스가 없음 = 생성
        if ($flagWrIndex != True) {    
            if ( hDB_createIndexCol ($lWriteTable, $lWriteTable_IndexName, $lIndexCol) != True) {
                // Error
            }
        }
    } else {
        // wr_last 로 비세팅 , 인덱스가 있음 = 삭제
        if ($flagWrIndex == True) {    
            if (hDB_dropIndexName ($lWriteTable, $lWriteTable_IndexName) != True) {
                // Error
            }
        }
    }
}    

=================================================
요청 내용에 적용한 예 (테스트는 되어 있지 않습니다.)
-------------

$lWriteTable = "g5_point";        // 인덱스 테이블 : g5_point
$lIndexCol = "po_expire_date";    // 인덱스 필드 : po_expire_date
$lIndexName = "index2";            //인덱스 키 명 : index2

// Test
$flagWrIndex = False;
$flagWrIndex = hDB_findColIndex ($lWriteTable, $lIndexCol);
if (! $flagWrIndex) echo "{$lWriteTable} {$lIndexCol} 컬럼의 인덱스 값이 존재 하지 않습니다.";

// 생성은 인덱스 컬럼으로 생성
if ( hDB_createIndexCol ($lWriteTable, $lIndexName, $lIndexCol) != True) {
    // Error
}
            
// 삭제는 인덱스 "명" 으로 삭제
if (hDB_dropIndexName ($lWriteTable, $lIndexName) != True) {
    // Error
}
답변을 작성하시기 전에 로그인 해주세요.
전체 1,543
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT