Warning: Undefined array key "mobile_dir" in /home/kagla/new-sir/old/common.php on line 315
디비 테이블 key 존재여부 확인후 쿼리 실행

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

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

QA

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

답변 3

본문

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
}
답변을 작성하시기 전에 로그인 해주세요.
QA 내용 검색
질문등록
전체 129,406
© SIRSOFT
현재 페이지 제일 처음으로