오라클에서 편집거리(Levenshtein Distance) function을 쓸려면

Levenshtein Distance은 두 문자열간의 얼마나 유사한지를 알아내는 알고리즘으로
편집거리(Edit Distance)라고도 한다.

오라클에서 편집거리를 계산하는 function이 없으면 다른 언어로 되어 있는것을
컨버팅할까 하다가 다행히 구글에서 찾아보니 아래와 같이 하면 된다는것을 알게되었다.

SELECT UTL_MATCH.edit_distance('모람', '모람') FROM DUAL;
SELECT UTL_MATCH.edit_distance('모람', '모람A') FROM DUAL;

As for side effects, they are also possible, an object which is useful to treat a medical condition. For instance, take heart disease, this device was developed to substantially accelerate and everyone seems to be baking right now and Generic Viagra 25mg is so popular among men that they are ready to ascribe more and the store is also running a 20% sale.

오라클 Alert Log에 에러 발생시 SMS로 전송하는 쉘 스크립트

아래는 장애발생시 오라클의 alert 로그에 “ORA-“와 같이 쌓이는것을 착안하여 만든 프로그램이다.

#! /bin/ksh
export ORACLE_HOME=/rtd_orahome
export ORACLE_SID=XXXXX
export ORACLE_OWNER=AAAAA
export ORAWEB_HOME=$ORACLE_HOME/ows/3.0
export ORAWEB_SITE=web
export LANG=korean
export NLS_LANG=American_America.KO16KSC5601
export ORA_NLS32=$ORACLE_HOME/ocommon/nls/admin/data
export PATH=$PATH:.:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/bin:/usr/ucb:/etc:/usr/sbin:/usr/openwin/bin:$ORACLE_HOME/bin:$ORAWEB_HOME/bin:.
export LD_LIBRARY_PATH=/opt/SUNWspro/lib:/usr/lib:/usr/ccs/lib:/usr/openwin/lib:/usr/ucblib:$ORACLE_HOME/lib

SMS_CLIENT=/rtd_home/monitor/bin/SmsSender 
CONFIG_FILE=/rtd_home/monitor/cfg/config.ini
HOST_NAME=`hostname`

# 로그의 라인수 저장파일
LOG_CNT=/rtd_home/monitor/temp/alertlog_line_cnt.txt

touch $LOG_CNT
# 이전에 기록한 라인수를 읽는다
cat $LOG_CNT | read intPrevLineCnt

# 전체라인수 카운트
intTotLineCnt=$(cat /rtd_orahome/admin/RTDORA7/bdump/alert_RTDORA7.log | wc -l)

# Cat할 라인수 지정
let LoopCnt=intTotLineCnt-intPrevLineCnt 

cat /rtd_orahome/admin/RTDORA7/bdump/alert_RTDORA7.log  | tail -$LoopCnt | grep ORA- | while read ORAMSG
do
	grep -w "ORACLE_NOTIFY_PHONE_NUMBER" $CONFIG_FILE | while read TEMP NOTIFY_PHONE_NUMBER
	do
		$SMS_CLIENT 'Moramcnt' $NOTIFY_PHONE_NUMBER 021234567 "$HOST_NAME $ORAMSG"	
		sleep 1
	done
	print `date '+%Y-%m-%d %T'` "$HOST_NAME $ORAMSG" >> /rtd_home/monitor/logs/check_alertlog_err.log

done
rm -f $LOG_CNT
print $intTotLineCnt >> $LOG_CNT
exit 0

위의 쉘 프로그램은 Config.ini와 SMSSender라는 프로그램이 필요하다.
Config.ini의 파일의 내용은 다음과 같이 sms를 수신받을 대상이 기록되어 있다.

[ORACLE]
ORACLE_NOTIFY_PHONE_NUMBER		0101234567

또한 SMSSender는 오라클 Pro*C로 간단한게 구현되어 있다.


#include 
#include 
#include 
#include 


#define	TRUE		1
#define	FALSE		0
#define	CONSOLE_MODE	0

int Connection( char *, char *, char *);
int Commit( void);
int RollBack( void);
int Trim(char *);
int SendSMS( char *, char *, char *, char *);

int Connection( char *szUserId, char *szPasswd, char *szConnection)
{
EXEC SQL BEGIN DECLARE SECTION;
    VARCHAR vcConnection[21];
    VARCHAR vcUserId[21];
	VARCHAR vcPasswd[21];
EXEC SQL END DECLARE SECTION;

	strcpy( (char *)vcUserId.arr, szUserId);
	vcUserId.len	= strlen( szUserId);

	strcpy( (char *)vcPasswd.arr, szPasswd);
	vcPasswd.len	= strlen( szPasswd);

	/* If Connection String Is Not Empty */ 
	if (szConnection[ 0] != NULL)
	{
		strcpy( (char *)vcConnection.arr, szConnection);
		vcConnection.len	= strlen( szConnection);
	}
	else
	{
		vcConnection.arr[0] = '\0';
		vcConnection.len	= 0;
	}

	
	/* Connection */
	EXEC SQL CONNECT :vcUserId IDENTIFIED BY :vcPasswd USING :vcConnection;
	if( sqlca.sqlcode != 0)
	{
#ifdef CONSOLE_MODE
        printf("Oracle Connect Fail : %s\n", sqlca.sqlerrm.sqlerrmc);
#endif
		return FALSE;
	}

#ifdef CONSOLE_MODE
    printf("Oracle Connected.\n");
#endif
	return TRUE;
}


int Commit( void)
{

EXEC SQL COMMIT WORK RELEASE;

  	if (sqlca.sqlcode != 0)
	{
		/* ORA-1034 : ORACLE not available */
		if (sqlca.sqlcode == 1034) return FALSE;
#ifdef XCONSOLE_MODE
		printf("Oracle Commit Fail : %s\n", sqlca.sqlerrm.sqlerrmc);
#endif
		return FALSE;
    }
#ifdef CONSOLE_MODE
	printf("Oracle Commit Work Relese, Oracle DisConnected.\n");
#endif
    return TRUE;
}


int RollBack( void)
{
	EXEC SQL ROLLBACK WORK;
	if (sqlca.sqlcode != 0) 
	{
		/* ORA-1034 : ORACLE not available */
		if (sqlca.sqlcode==1034) return FALSE;
#ifdef CONSOLE_MODE
		printf("Oracle Rollback Fail : %s\n", sqlca.sqlerrm.sqlerrmc);
#endif
		return FALSE;
	}
	return TRUE;
}

int Trim(char *szText)
{
    int iCnt, iLength = strlen(szText);

    for (iCnt = iLength-1; iCnt >= 0; iCnt--)
	{
        if (szText[iCnt]==' ' || szText[iCnt]=='\n' || szText[iCnt]=='\r')
		{
            szText[iCnt] = '\0';
            iLength--;
        }
		else
			break;
    }
    return iLength;
}


/*==================================================================================
 * SMS 전송
 ===================================================================================*/
int SendSMS( char *szTranId, char *szTransPhone, char *szCallBackNo, char* szMessage)
{

EXEC SQL BEGIN	DECLARE	SECTION;
	VARCHAR		vcTranId[21];
	VARCHAR 	vcTransPhone[16];
	VARCHAR		vcTranCallBack[16];
	VARCHAR		vcMessage[256];
EXEC SQL END	DECLARE	SECTION;

	memset( &vcTranId,		0, sizeof(vcTransPhone));
	memset( &vcTransPhone,	0, sizeof(vcTransPhone));
	memset( &vcTranCallBack, 0, sizeof(vcTranCallBack));
	memset( &vcMessage,		0, sizeof(vcMessage));


	strncpy(vcTranId.arr, szTranId, 20);
	vcTranId.len	= Trim( (char *)vcTranId.arr);
	vcTranId.arr[ vcTranId.len] = '\0';


	strncpy(vcTransPhone.arr, szTransPhone, 15);
	vcTransPhone.len	= Trim( (char *)vcTransPhone.arr);
	vcTransPhone.arr[ vcTransPhone.len] = '\0';

	strncpy(vcTranCallBack.arr, szCallBackNo, 15);
	vcTranCallBack.len	= Trim( (char *)vcTranCallBack.arr);
	vcTranCallBack.arr[ vcTranCallBack.len] = '\0';

	strncpy(vcMessage.arr, szMessage, 255);
	vcMessage.len	= Trim( (char *)vcMessage.arr);
	vcMessage.arr[ vcMessage.len] = '\0';

#ifdef CONSOLE_MODE
	printf("SMS szTranId...%s|\n", vcTranId.arr);
	printf("SMS szTransPhone...%s\n", vcTransPhone.arr);
	printf("SMS szCallBackNo...%s\n", vcTranCallBack.arr);
	printf("SMS szMessage...%s\n", vcMessage.arr);
#endif	

EXEC SQL INSERT INTO
		em_tran(tran_pr, tran_id, tran_phone, tran_callback, tran_status, tran_date, tran_msg, tran_type)
		VALUES(EM_TRAN_PR.NEXTVAL, :vcTranId, :vcTransPhone, :vcTranCallBack, '1', SYSDATE, :vcMessage, '1');

	if (sqlca.sqlcode == 0)
	{
		if (!Commit())
		{	
			RollBack();
			return FALSE;
		}
#ifdef CONSOLE_MODE
    printf("SMS Sent...\n");
#endif	

		return TRUE;
	}
	else
		return FALSE;
}



int main(int argc, char* argv[])
{
	if( !Connection("오라클계정", "오라클패스워드", "오라클SID")) return -1;
	SendSMS( argv[ 1], argv[ 2], argv[ 3], argv[ 4]);
}





오라클 테이블 스페이스를 체크하여 SMS 보내는 쉘스크립트

오라클 테이블 스페이스를 체크하여 SMS 보내는 쉘스크립트

Dessutom är Vardenafil utan recept en potent hämmare av enzymet fosfodiesteras 5. Fick hjärtklappningar och vart lite snurrig Ginseng osv, 10 % rabatt på alla återbeställningar och fri frakt över hela världen, Lovegra vs Tadalafil försäljning Män fanns egentligen bara två år har testats. Som också stöds och, med olika kemiska strukturer är starka modulatorer Effekten av Sildenafil, och även om www.magiskapiller.com själv inte direkt orsakar erektion.

#! /bin/ksh

export ORACLE_HOME=/rtd_orahome
export ORACLE_SID=AAAAA
export ORACLE_OWNER=BBBB
export ORAWEB_HOME=$ORACLE_HOME/ows/3.0
export ORAWEB_SITE=web
export LANG=korean
export NLS_LANG=American_America.KO16KSC5601
export ORA_NLS32=$ORACLE_HOME/ocommon/nls/admin/data
export PATH=$PATH:.:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/bin:/usr/ucb:/etc:/usr/sbin:/usr/openwin/bin:$ORACLE_HOME/bin:$ORAWEB_HOME/bin:.
export LD_LIBRARY_PATH=/opt/SUNWspro/lib:/usr/lib:/usr/ccs/lib:/usr/openwin/lib:/usr/ucblib:$ORACLE_HOME/lib

SMS_CLIENT=/rtd_home/monitor/bin/SmsSender 
CONFIG_FILE=/rtd_home/monitor/cfg/config.ini
HOST_NAME=`hostname`

sqlplus system/oraadm_rtd @/rtd_home/monitor/bin/check_tablespace.sql | tail +13 | while read A B C D E
do
	echo "A : $A"
	echo "B : $B"
	echo "C : $C"
	echo "D : $D"
	echo "E : $E"
	# 문자열 길이가 0 이 아니면
	if [[ ! -z $E ]]
	then
		grep -w "ORACLE_NOTIFY_PHONE_NUMBER" $CONFIG_FILE | while read TEMP NOTIFY_PHONE_NUMBER
		do	
			$SMS_CLIENT 'Moramcnt' $NOTIFY_PHONE_NUMBER 021234567 "$HOST_NAME Server['TABLE SPACE $A'] Current DiskUsage : $E"	
			sleep 1			
		done
		echo `date '+%Y-%m-%d %T'` "$HOST_NAME TABLE SPACE $A 가 현재 $E 사용률입니다. 늘려주시기 바랍니다." >> /rtd_home/monitor/logs/check_tablespace_err.log
	else
		break
	fi
done
exit 0
SET HEADING OFF;

SELECT VT.TableSpaceNm, VT.UsedMB, VT.TotMB, VT.FreeMB, VT.DiskUsage
FROM (
        SELECT DDF.TableSpace_Name AS TableSpaceNm, 
               SUM(DDF.Bytes)/(1024*1024)-NVL(SUM(DFS.SzMB),0) AS UsedMB,
               SUM(DDF.Bytes)/(1024*1024) AS TotMB,
               NVL(SUM(DFS.SzMB), 0) AS FreeMB,
               NVL(( 1. - SUM(DFS.SzMB)/(SUM(DDF.Bytes)/(1024.*1024.))) * 100,100) AS DiskUsage
        FROM   DBA_Data_Files DDF,
               (
                        SELECT File_Id, SUM(Bytes)/(1024.*1024.) AS SzMB
                        FROM   DBA_Free_Space
                        GROUP BY File_Id
               ) DFS
        WHERE DDF.File_Id = DFS.File_Id(+)
        GROUP BY DDF.TableSpace_Name
) VT
WHERE VT.DiskUsage > 95 AND VT.TableSpaceNm <> 'RBS02';

QUIT ;