블로그 이미지

유효하지않음

,


우리나라도 시급한데....~~
각종 범죄도 핀란드 교통 범칙금처럼 소득기준으로 했으면 좋겠네..~~~
블로그 이미지

유효하지않음

,





천지인신 하나되어 이내일신 탄생하니.


부생모육 그은혜는 하늘같이 높건마는.
청춘남녀 많은데도 효자효부 드물구나.
출가하는 딸아이는 시부모를 싫어하고.
결혼하는 아들네는 살림나기 바쁘도다.

제자식이 장난치면 싱글벙글 웃으면서.
부모님의 앓는소리 듣기싫어 외면하네.
시끄러운 아이소리 듣기좋아 즐기면서.
부모님의 말씀하면 잔소리라 관심없네.

자녀들의 대소변은 손으로도 주무르나.
부모님의 흘린침은 더럽다고 멀리하고.
과자봉지 들고와서 아이손에 쥐어주나.
부모위해 고기한근 사올줄은 모르도다.

개병들어 쓰러지면 가축병원 데려가도.
늙은부모 병이나면 노환이라 생각하네.
열자식을 키운부모 하나같이 키웠건만.
열자식은 한부모를 하나같이 싫어하네.

자식위해 쓰는돈은 한도없이 쓰건마는.
부모위해 쓰는돈은 한두푼도 아깝다네.
자식들을 데리고는 바깥외식 자주하나.
늙은부모 모시고는 외식한번 힘들구나.

아들있고 딸있는데 양로원이 웬말인가.
늙은것도 원통한데 천대받고 괄세받네.
너도늙은 부모되면 애고지고 설울지라.
살아생전 불효하고 죽고나면 효자날까.

예문갖춰 부고내고 조문받고 부조받네.
그대몸이 소중커든 부모은덕 생각하고.
내부모가 소중하면 시부모도 소중하다.
부모님이 죽은후에 효자나고 효부나네.

가신후에 후회말고 살아생전 효도하세
생각하고 말을하고 생각하고 행동하라.

블로그 이미지

유효하지않음

,

니들 그러면 안된다. 적어도 군사/군대 문제로 노무현 까서는 안되는것이다. 그게 도리다.

행여라도 까는 사람있으면, 장성들이 꾸짖어줘야지.. 입다물고 있는 장성들.. 너거도 그럼 못쓴다.


아래 증거자료들

 

KT-1 기본훈련기, T-50 고등훈련기, 손원일급 잠수함, 정찰위성

 

피규어가 득실득실한 밀덕후 노무현의 집무실.

 

위치가 자주 바뀐걸로 봐선 쉬는시간에 삐융삐융 콰쾅 하면서 갖고 노시는 듯.

 

 

(아랫분이 올리신 사진에 보이는 2MB의 책상과 오나전 다름)

http://shukri.tistory.com/248

-------------------------------------------------------------

 

(상) 국가대표 밀덕후 = 노간지의 책상 모습

(하) 말이 되냐? 세상에 이런 빨갱이가 어딨냐? 자주국방을 꿈꾸며 국방력 강화에 힘쓴 노간지

 

 ---------------------------------------------------------------------

1. 닥치고 국방예산 증강 크리

(98년 한국 국방예산 14조, 2008년 노무현정부가 짠 국방예산 24조 6천억원)

 

2. 사단수 반토막으로 장군들 보직수 대폭 감소 = 효율화

 

3. 2020년말까지 해군 3개 기동전단 확보 떡밥 유포

 

4. 세종대왕함 진수. 동급함 3척 추가 확보 추진

- 세종대왕함 : 해군의 꿈이 집결된 KDX-3함. 이로써 세계 다섯번째 이지스함 보유국. 말로나마 키로프급과 맞짱을 띄워볼 수 있는 최신예 함정. 일본 이지스 '아타고'급보다 시스템및 미사일 탑재량면에서 우세. 사거리 500km의 천룡 함대지 크루즈 미사일 32발 탑재. '가라 천룡' 한마디에 도쿄 불바다 가능. 대함미사일 탑재량 일반적인 서방의 두배 - 고무뽀트에도 야혼트를 싣는 무대뽀 러시아식 교리

 

5. 러시아 초음속 대함 미사일 최신기술 갈쳐달라고 징징징.

- 러시아 초음속 미사일들 : 러시아는 초음속 대함미사일에서 세계 최고수준. 쏘고 도망가버리면 미사일이 지들끼리 공격 포메이션을 짜서 어떤놈은 위에서 냅다 꽂고 어떤놈은 수면에 살살 스치며 가고 어떤놈은 새로 찾은 다른 함으로 달려가고... 근데 이렇게 날아가는 미사일이 크기는 전봇대 만하고 속도는 초음속. 이거만 왕창 사두면 일본 함대는 독도 근처에도 못올거임. 자체 생산이라도 했다간 어이구... 이거 포함 암튼 최신예 군사기술 9가지인가 도입 확보.

 

6. 글로벌 호크 미국에서 안판다고 안판다고 하는 걸 징징짜고 메달리고해서 4대 도입 약속.

- 글로벌호크 : 트랜스 포머 사막전투씬에 나온 그 무인 항공기. 한번뜨면 대륙간 왕복, 오존층 쪼끔 밑에서 30시간동안 동동 떠서 지상의 30cm물건까지 식별 가능, 북한 전역정도는 한방에 감시 가능한 몹쓸 치트유닛. 아니 맵핵

 

7. 미국이 가져가라고~ 가져가라고 하던 전작권 회수 2009년에서 2012년으로 늦춤. 우기고 우겨서 전작권 돌려받았다는 소리는 조중동의 헛소리. 정보력의 부재에서 올 약점을 커버하고자 글로벌호크 도입

 

8. 스타 포트라도 지은 양 국산 공중유닛 신나게 뽑아댐. KT-1 기본훈련기, T-50 고등훈련기 등등등...

 

9. 공포의 76km 함포 탑재 행성간 결전병기 윤영하함 건조 (ㅋㅋㅋ)

 

10. 아시아 최대의 강습상륙함을 지어놓고 이름을 '독도함'이라고 붙임....

완전 개깡다구 싸나이 갑빠.

 

 

11. 그외 자잘한 함선들 엄청 뽑아냄


국가 원수의 지름신을 부추기는 공군 장성 아저씨 '형 나 저거 사죠' '응 알았엉♡'


 


12. 스웨덴, 이탈리아 꼬셔서 함께 KFX 차세대 전투기 만들기로 미래를 약속~♡ 니네가 만들면 우리가 살께 하고 브라질과 아랍에미리트가 산다고 나섰음.

시발 드디어 국산 전투기다!

  

13. 육군 유닛도 버리지 않으심

K1A1 191대에서 484대로 291대 증가, 예산은 1조 491억에서 2조 8733억원으로 폭등

K-9 255대에서 532대로 증가, 예산은 1조 9420억원에서 3조 4723억원으로 폭등

차세대 전차 K-2 예산 2조 9000억원에서 5조 7692억원으로 또 폭등 수량도 2배

K-21은 천여대 이상 예산은 총 4조 1978억으로 역시 폭등

차륜형 장갑차도 300~400대 규모에서 2000~3000대 규모로 10배 폭등

K-55 자주포 1100대에 팔라딘급 개량

맨날 욕처먹는 비호와 천마 예산 절반 잘라먹고 그 돈으로 맨패드 대공미사일 수량 폭등, 차기 차륜형 대공포 개발, 비호 + 신궁 복합체계 개발

예산 증가 도입대수 증가 개발 개발 폭등 폭등 개발 폭등 추가 도입 개발....




 콜렉션 앞에서 기뻐하는 밀덕후와 밀덕 카페 회원들

 

14. 육군의 신형 공격 헬리콥터 KAH 개발 추진. 아주 그냥 전부다 국산화하신다.

 

15. E-737 공중조기경보통제기 도입 추진 이쯤되면 막가자는 거지요?

 

  

                            이 아저씨 재임시절의 국방력 강화를 위한 행보들을 보면

 

자칭우익이라는 것들이 말하길 "좌익 빨갱라고부르던 이 아저씨야말로

 

사실 우익 보수라는 생각이 든다.

 

유럽 복판에 갖다놔도 별로 꿀릴건 없고

 

동남아 어디쯤만 되었어도 동네 깡패로 불렸을만한 국방력

 

중-러-일-미 세계 4대 강대국에 끼인 이 기막힌 위치에서도

 

'언제까지 북한만 상대하고 있을거냐'면서

 

호쾌한 싸나이의 기개를 펼치던 노무현각하.

 

은근히 미국에서도 얻을거 다 얻어내면서

(글로벌호크 구매와 함께 무기판매국가 지위 격상)

 

또다른 강대국 러시아와의 관계를 모색하던 실리 외교의 달인.

 

국방력 증강에 대한 집념이 거의 우익 군국주의자 수준인

 

이 양반은 좌익 좌빨 빨갱이소리를 듣는데,

 

 

자칭 건전 보수 실용주의 이메가는

 

저거 유지는 고사하고 취소, 중단만 날려대고 계신다.

 

북한 전역을 한번에 감시가능한 글로벌호크를 취소하고

 

여의도 72배 군사시설 보호구역 헤제하고

 

 수도권 방공의 핵심인 성남 공항마저

 

롯데월드 지으라고 이전시키는 양반은 뭔가? 

 

찌라시, 딴나라, 알밥들로부터 그렇게 친북좌빨이라 욕을 먹었지만

단군이래 최대의 군사력,국방력을 만든 분... 

 

그러면서도 유일한 현역 사병출신이라 사병들 처지를 알아준 대통령...

 

대통령 당선후..군복무하던 **사단 가시면서..

 

괜희 나때문에 병사들 연병장에 몇시간 집합시키지말라..........

 

군복무중....부모님께...돈 부쳐 달라하지말라......

 

(지금은 병장 월급이 거의10만원...아직도 많이 부족하지만.) 

-------------------------------------------------------------- 

 

(한겨례 중 발췌)

 

8일 새벽 4시30분께 프랑스 파리 상공대통령 특별기 안.

 

“이 비행기는 서울로 바로 못 갑니다. 쿠웨이트에 들러서 에르빌을 다녀와야겠습니다.

에르빌에 새벽에 도착해 장병들과 아침식사를 같이 먹을 수 있습니다.”

 

노무현 대통령이 예고에 없던 즉석 회견에서 자이툰 부대 방문 계획을 처음으로 공개.

한순간 침묵이 흘렀다.

애초 이날 새벽 4시 파리를 출발해 오후 4시께 서울공항에 도착하려던 일정은 이렇게 바뀌었다.  






이라크에 파병중인 자이툰사단을 방문 장병들과 아침식사전 음료수로 건배하고 있다.

에르빌/탁기형 기자  (한겨례)


노 대통령...배식대에서 직접 식판을 들고 밥과 반찬을 담으며

“배추는 서울에서 직접 가져오느냐”라고 묻기도.


 

노 대통령은  “통수권자로서 부끄럽지 않게 하겠다. 대한민국 정치지도자로서

적어도 제 양심에 부끄러움이 없도록 할 것”이라고 다짐하기도 했다.


 

앞서 여군인 김세령 중사는 “대통령님을 직접 만나게 돼 로또 1등에 당첨된 것보다 더 영광이다”

이원경 병장은 “꿈인지 생시인지 분간이 안 간다. 대한민국 국민임을 잊지 않고 자부심을 가지고 근무할 것”이라고 말했다.

 

 

경호원들 화들짝 놀랬을게요.크크.. 

 

자이툰 부대 방문때 해병대 상병이 용감하게 포옹을하오.

 

그걸 받아주는 대통령..

 

아마..대한민국 역사상 대통령을 포옹한 첫 사병..감동 먹었소.

 

보통 경호원들때문에 차단되는데..저 해병대원...정말...대단했소.

 

 

떠날 때 맘이 아파서...

 -----------------------------------------------------------------

 

 

 

롯데월드 좋아~ 퓽~퓽~

 

(펌의 펌이지만... 원래 출처는...

즐보드 퍼렁놀님 이신 듯.)

 

http://bbs2.agora.media.daum.net/gaia/do/kin/read;jsessionid=B8DE28ECBC090372481BB6C91093BBA9?bbsId=K150&searchKey=&resultCode=200&sortKey=depth&searchValue=&articleId=575304&TOKEN=ad7ac1d90b167d4727b5f2fbe8f1cf9

이렇게 자주국방에 초석을 다지던 우리 대한민국이 쪽바리 2mb가 대통령이 되면서....

 

노무현 

국방개혁 2020으로 인해 2020년까지는

국방비가 매년 7-9%씩 증가
2020년까지 630조 예산 증가


이명박

한나라당 노무현 정부의 국방개혁 2020 반대

국방예산 599조로 31조 삭감

 

 

노무현

극동아시아 전 지역을 샅샅이 감시할 수 있는

고고도 무인 정찰기 글로벌호크

노무현 정권 말년 때

타국에 판매하지도 않았고,

한국에게 안팔겠다는 미국한테 끈질기게 요청해

4대 도입 계약 이뤄냄

북한은 물론 일본중국이 이번 일로 한국군 급 견제

(영화 트랜스포머 사막 전투씬에 나온 무인 항공기)

 

 

 

이명박

노무현이 말년에 이뤄낸 큰 성과 글로벌호크 도입 예정 취소

KFX 한국형 전투기 폐지

(스웨덴, 이탈리이랑 함께 만들어서

브라질, 아랍에미리트가 살 예정이었던 국산 전투기)

KAH 한국형 공격헬기 폐지

이 일로 보수성향 장군들 이명박에게 실망함

 

 

노무현

자주국방을 위해 전시작전권 환수

 

 

이명박

제2롯데월드 건설 위해

대북 정찰 감시, 안보 핵심 기지인 성남공군기지 이전 지시

전쟁 나면 수도권 5분만에 초토화 예정

 

 

노무현

FFX사업추진,

무인폭격기 개발,

F-15K 60대 계약,

K1A1 484대 증가,

예산 약 3조원으로 증가,

K-9 532대 증가

예산 3조 5천억원으로 증가,

차세대 전차 K-2 예산 5조 7천억원으로 증가,

K-21 예산 4조 1천억원으로 증가,

차륜형 장갑차 3000대 규모로 증가,

K-55 자주포 1100대에 팔라딘급 개량,

맨패드 대공미사일 수량 폭등,

조기경보기 4대 계약, P-3 해상초계기 8대 계약,

3000톤급 잠수함 개발

JDAM 900발 도입

유도탄 사령부 창설 북한 장사정포 겨냥

제주도 해군 기지 건설

이순신함 5척, 세종대왕함 1척, 손원일,정지함 2척 건조

천룡 함대지 크루즈 미사일 32발 탑재

(동해 건너 일본 불바다 가능)

 

아시아 최대의 강습상륙함 독도함 개발

세계 국가 중 다섯번째로 이지스함 보유

(일본 이지스함보다 뛰어남)

 

 

이명박

호텔, 아파트 건설 위해 파주 군 보호구역 해제 및

위 기록한 무기, 전차, 공군 헬기 등 폐지 및 취소

 

 

노무현

독도 문제 관련 특별담화 발표 일본에게 강력 경고

동해 문제 관련 일본의 '평화의 바다' 제안 거부

미국의 요청에 이라크 파병 지원

북한 핵개발 관련 강력 경고, 북한 핵개발 취소

 

 

이명박

북한 로켓 발사, 핵미사일 다시 개발

 

 

노무현

노무현 정권 5년 내에 육군력 세계 3위,

해군, 공군 세계 10위 안으로 격상시킴

세계 최고 성능의 항공모함 어뢰와 기술력 보유,

실제 세계 해군 태평양훈련에서

유일하게 한국 해군이 명중률 100%,

유일하게 일본의 이지스함과 미국 항공모함을 격침

(아 이순신 장군이 눈물 흘리며 뿌듯해하실 일이다ㅜㅜ)

일본과 전쟁시 한국이 승리할 확률 90%

(독도 문제 때 일본에게 강력 경고할 수 있던 여유와 이유)

 

 

이명박

노무현이 계약한 최신 무기와 이지스함 등

이명박이 취소 및 폐지로

현재 일본과 독도 문제로 총력전 치룰 경우 승리 확률 60%로 격하

더 취소하거나 폐지할 경우 한국군 승리 확률 40%로 폭락

 

------------------------------------------------------

출처: 밀리터리매니아

블로그 이미지

유효하지않음

,
SELECT UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW('1234nextguide'))) FROM dual;
SELECT UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW('MTIzNG5leHRndWlkZQ=='))) FROM dual;

SELECT UTL_ENCODE.TEXT_ENCODE('1234nextguide', 'WE8ISO8859P1', 1) FROM dual;
SELECT UTL_ENCODE.TEXT_DECODE('MTIzNG5leHRndWlkZQ==', 'WE8ISO8859P1', 1) FROM dual;


/*------------------------------------------------------------------------------
-- 개체명 : B2C
-- 생성일 : 2010-03-22 오후 3:03:32
-- 최종수정일 : 2010-03-22 오후 3:03:39
-- 상태 : VALID
------------------------------------------------------------------------------*/
CREATE OR REPLACE FUNCTION B2C(B IN BLOB) RETURN CLOB -- TYPECASTS BLOB TO CLOB (BINARY CONVERSION)
IS
    pos       PLS_INTEGER  := 1;
    buffer    VARCHAR2( 32767 );
    res       CLOB;
    lob_len   PLS_INTEGER  := DBMS_LOB.getLength(b);
BEGIN
    DBMS_LOB.createTemporary(res, TRUE);
    DBMS_LOB.OPEN(res, DBMS_LOB.LOB_ReadWrite);

    LOOP
        buffer := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b, 16000, pos));

        IF LENGTH( buffer ) > 0
        THEN
            DBMS_LOB.writeAppend( res, LENGTH( buffer ), buffer );
        END IF;

        pos := pos + 16000;
        EXIT WHEN pos > lob_len;
    END LOOP;

    RETURN res; -- res is OPEN here
END b2c;


/*------------------------------------------------------------------------------
-- 개체명 : C2B
-- 생성일 : 2010-03-22 오후 3:03:32
-- 최종수정일 : 2010-03-22 오후 3:03:39
-- 상태 : VALID
------------------------------------------------------------------------------*/
CREATE OR REPLACE FUNCTION C2B(C IN CLOB) RETURN BLOB -- TYPECASTS CLOB TO BLOB (BINARY CONVERSION)
IS
	pos       PLS_INTEGER  := 1;
    buffer    RAW( 32767 );
    res       BLOB;
    lob_len   PLS_INTEGER  := DBMS_LOB.getLength(c);
BEGIN
    DBMS_LOB.createTemporary(res, TRUE);
    DBMS_LOB.OPEN(res, DBMS_LOB.LOB_ReadWrite);

    LOOP
        buffer := UTL_RAW.CAST_TO_RAW(DBMS_LOB.SUBSTR(c, 16000, pos));

        IF UTL_RAW.LENGTH(buffer) > 0
        THEN
            DBMS_LOB.writeAppend(res, UTL_RAW.LENGTH(buffer), buffer);
        END IF;

        pos := pos + 16000;

        EXIT WHEN pos > lob_len;
    END LOOP;

    RETURN res; -- res is OPEN here
END c2b;


/*------------------------------------------------------------------------------
-- 개체명 : BASE64_B2C
-- 생성일 : 2010-03-22 오후 3:03:32
-- 최종수정일 : 2010-03-22 오후 3:03:39
-- 상태 : VALID
------------------------------------------------------------------------------*/
CREATE OR REPLACE FUNCTION BASE64_B2C(B IN BLOB) RETURN CLOB
IS
	v_buffer_size	INTEGER  := 4096;
	v_buffer_raw	RAW(4096);
	v_offset		INTEGER DEFAULT 1;
	v_clob			CLOB;
BEGIN
	DBMS_LOB.createTemporary(v_clob, FALSE, DBMS_LOB.CALL);

	LOOP
		BEGIN
			DBMS_LOB.READ(b, v_buffer_size, v_offset, v_buffer_raw);
			EXCEPTION
				WHEN NO_DATA_FOUND THEN
            EXIT;
        END;

        v_offset := v_offset + v_buffer_size;
        DBMS_LOB.APPEND(v_clob, to_clob(utl_raw.cast_to_varchar2(utl_encode.base64_encode(v_buffer_raw))));
    END LOOP;

    RETURN v_clob;
END BASE64_B2C;


/*------------------------------------------------------------------------------
-- 개체명 : BASE64_C2B
-- 생성일 : 2010-03-22 오후 3:03:32
-- 최종수정일 : 2010-03-22 오후 3:03:39
-- 상태 : VALID
------------------------------------------------------------------------------*/
CREATE OR REPLACE FUNCTION BASE64_C2B(C IN CLOB) RETURN BLOB
IS
	v_blob				BLOB;
	v_offset			INTEGER;
	v_buffer_varchar	VARCHAR2(4096);
	v_buffer_raw		RAW(4096);
	v_buffer_size		BINARY_INTEGER := 4096;
BEGIN
	IF c IS NULL
	THEN
        RETURN NULL;
    END IF;

    DBMS_LOB.createTemporary(v_blob, TRUE);
    v_offset := 1;

    LOOP
        BEGIN
            DBMS_LOB.READ(c, v_buffer_size, v_offset, v_buffer_varchar);
            EXCEPTION
                WHEN NO_DATA_FOUND THEN
            EXIT;
        END;

        v_buffer_raw := UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(v_buffer_varchar));
        dbms_lob.writeAppend(v_blob, UTL_RAW.LENGTH(v_buffer_raw), v_buffer_raw);
        v_offset := v_offset + v_buffer_size;
    END LOOP;

    RETURN v_blob;

END BASE64_C2B;
블로그 이미지

유효하지않음

,

블로그 이미지

유효하지않음

,
var hwpCtrl	= document.frm.HwpCtrl;
var uploadCtrl	= document.frm.UploadCtrl;


var ActiveXDetector = 
{
	//ACTIVEX_OBJECT_NAME: "NextGuideHwpBridge.NextGuideHwpBridgeX",
	getActiveX: function(ProgId)
	{
		try
		{ 
			var obj = new ActiveXObject(ProgId);
			if(obj) return obj;
			else ret = null;
		}
		catch(e)
		{ 
			ret = null;
		}
		
		return ret; 
	}
}

if(ActiveXDetector.getActiveX('NextGuideHwpBridge.NextGuideHwpBridgeX'))
{ 
	alert("ActiveX 설치"); 
}
else
{
	alert("ActiveX 설치 안됨"); 
}


function ActiveXInstalled(ProgId)
{
	var isInstall = false;

	try
	{
		var obj = new ActiveXObject(ProgId);
		if (obj) return true;
	}
	catch (e)
	{
		return false;
	}
	return false;
}

if(ActiveXInstalled('NextGuideHwpBridge.NextGuideHwpBridgeX'))
{ 
	alert("ActiveX 설치"); 
}
else
{
	alert("ActiveX 설치 안됨"); 
}


var bnResult = (typeof(uploadCtrl.GetDOM) == "undefined")? true : false;
//var bnResult   = (typeof(uploadCtrl.GetDOM) == "unknown")? true : false;

if(bnResult)
{ 
	alert("ActiveX 설치"); 
}
else
{
	alert("ActiveX 설치 안됨"); 
}
블로그 이미지

유효하지않음

,

[출처] http://moraledu.net/gnuboard4/bbs/board.php?bo_table=menu01_father&wr_id=112.


그들이 처음 왔을 때
 
나치는 우선 공산당을 숙청했다.
나는 공산당원이 아니었으므로 침묵했다.
 
그 다음엔 유태인을 숙청했다,
나는 유태인이 아니었으므로 침묵했다.
 
그 다음엔 노동조합원을 숙청했다.
나는 노동조합원이 아니므로 침묵했다.
 
그 다음엔 가톨릭교도를 숙청했다.
나는 개신교도였으므로 침묵했다.
 
그 다음엔 나에게 왔다.
그 순간에 이르자, 나서줄 사람이 아무도 남지 않았다.
 
******************************************************
 
마르틴 니묄러 [1892.1.14~1984]  
 
제1차 세계대전 중에는 U보트의 함장이었으나 전후 성직자가 되어, 1931~1937년 베를린 달렘의 루터교회 목사를 역임하였다. 나치스의 종교정책에 저항했기 때문에 1937∼1945년 강제수용소에 수용되었다. 제2차 세계대전 후에는 동서 독일의 통일을 주장하며, 서독의 재군비확충에 끝까지 반대하는 등, 평화주의 운동의 지도자로서 크게 활약하였다. 독일복음주의교회 평의원 ·외무국장, 세계교회협의회 의장단의 일원이었다. 저서에 《U보트에서 설교단으로》(1934) 《교회의 혁신》(1946) 등이 있다.
 
원어명  Friedrich Gustav Emil Martin Niemoller  
국적  독일  
활동분야  종교 
 
<출처 두산백과사전 EnCyber & EnCyber.com>
블로그 이미지

유효하지않음

,
블로그 이미지

유효하지않음

,
블로그 이미지

유효하지않음

,

맛집소개...

기타 2009. 11. 18. 22:19
487회 2009.10.16 방영분
조개구이반&찜반/조개싹쓸이/02)485-8293, 02)478-0153
서울시 강동구 성내동 50-5번지 (천호동)
※사정에 따라 문어가 낙지로 대체될 수 있습니다. 

Get Microsoft Silverlight




국밥 : 055-573-0303 <종로식당> 경남 의령군
 

Get Microsoft Silverlight


흑돼지 김치찌개 : 02-3426-5120 <장독 흑돼지> 서울 강동구

Get Microsoft Silverlight
블로그 이미지

유효하지않음

,

부자가 되는법 10가지

  1. 일찍 일어나라.

 2. 부지런 해라. 

 3. 인맥관리에 철저해라.

 4. 자기 자랑을 하지말라. (겸손하라) 

 5. 메모를 하라.

 6. 책을 읽어라. (하루에 적어도 100p) 

 7. 자기가 하는 일에 흥미를 느껴라.

 8. 인사를 잘하라. 

 9. 항상 웃어라.

10. 긍정적인 생각을 해라. 
                                                                                                       

   부자가 될 수 없는 법 7가지


 1. 책임을 타인에게 넘긴다.
      세상 모든 바보들은 항상 남의 탓만 한다.

 2. 말만 한다.
      새벽에 양재천이나 대모산에 올라가면 기업의 CEO나 부자들 즉 나름대로 성공의 길을

      걷는 사람들을 만날 수 있다. 그들이 그렇게 부지런을 떠는 게 우연이 아니다.
      아침 늦게 일어나고 게으르면서도 입만으로는 부자 될 것이라고 한다.
      입만 동동거려서 부자 될 것 같으면 이 세상에 부자 되지 못할 사람이 어디 있겠나?
      부자란 남다른 사람이다. 부자 되려면 지금부터 당장 실천하자!

 3. 정확한 목표가 없다.
      목표가 없는 사람은 초점이 없기에 아무것도 이룰 수 없다.
      초점이 없는 레이저 빔이 장애물을 관통할 수 있나? 안된다.
      성공하는 사람은 자신의 재능과 열정을 집중할 줄 아는 사람이다.
      부자 되려면 구체적인 장단기 목표를 세워야 한다!

 4. 쉬운 길, 편안한 길만 찾는다.
      당신이 남보다 특별한 재능이 있는가? 당신이 남보다 대단히 머리가 좋은가?
      평범한 당신이 부자 되려면 남보다 부지런하고 절약해야 하는 게 기본이다.
      어려움 없이 성취되는 것은 하나도 없다.
      남들처럼 입을 것 다 입고 먹을 것 다 먹고 놀 것 다 놀고 그러고 나서 평범한 당신이

      부자가 되겠다고 생각한다면 대단한 착각이다.
      남처럼 편안하게 살면서 부자 되겠다고 생각하는 사람은 도둑놈 심뽀를 가진 것이다.

 5. 협력자가 없다.
      다른 사람들과 협조하며 성공의 길을 간다면 쉽고도 빠르게 갈 수 있다.
      사람에 투자하라! 최고의 수익률은 주식도 부동산도 아니다. 바로 사람(협력자)이다.

 6. 작은 돈을 소홀히 한다.
      푼돈 아껴서 뭐해? 이렇게 말하는 사람은 부자 되기 틀렸다.
      거대한 배가 침몰하는 것도 작은 구멍 때문이다.
      자투리 돈을 관리하지 못하는 사람은 큰 돈도 관리하지 못한다.
      작은 돈을 잘 관리하지 못하는 사람이 어떻게 큰 돈은 잘 운용할 수 있단 말인가?
      한턱 잘 내고 푼돈을 소홀히 하는 사람은 결코 부자 되기 어렵다.

 7. 너무 빨리 단념한다.
      미국의 한 통계에 따르면 투자의 처음 10년간은 돈을 벌지 못한다는 보고서가 있다.
      투자도 연습하고 연마해야 잘하는 것이다.
      처음부터 잘한다면 그게 이상한 것 아닌가?
      처음부터 골프를 잘 칠 수 있나?  처음부터 4할 대 타자가 될 수 있나?

      돈 문제도 마찬가지이다.
      처음엔 10단위 투자해서 한 단위를 얻는다.
      나중에 1단위투자하고 10단위를 얻을 수 있다. 절대 포기하지 마라.
      그동안 투자로 날린 돈이 헛된 돈이 아니다. 수업료를 내고 배운 것이다.
      성공하는 비결은 어떠한 어려운 상황에서도 절망하지 않는데 있다. 

블로그 이미지

유효하지않음

,

[참조] smartsql.tistory.com

sqlplus 실행시 @를 붙여 별도의 sql문을 실행하면서 해도 되지만
파일을 별도로 관리해야 되는 번거로움 때문에 쉘스크립트상에서 실행하기로 했음

crontab 에 등록시
4 19 * * * /oracle/shell/call_proc_profit_dist.sh  >> /oracle/shell/log/proc_profit_dist.log

file: call_proc_profit_dist.sh

#!/bin/bash
export ORACLE_BASE=/oracle
export ORACLE_HOME=/oracle/10.2.0
export ORACLE_OWNER=oracle
export ORACLE_SID=kumc
export TNS_ADMIN=$ORACLE_HOME/network/admin
export ORA_NLS10=$ORACLE_HOME/nls/data
export NLS_LANG=KOREAN_KOREA.KO16MSWIN949
export NLS_NCHAR=KOREAN_KOREA.UTF8
export NLS_DATE_FORMAT=YYYYMMDD
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$ORACLE_HOME/lib32:$ORACLE_HOME/rdbms/demo:$ORAClE_HOME/oracm/lib:/lib:/usr/lib:/usr/local/lib
export LDPATH=$ORACLE_HOME/lib:$ORACLE_HOME/lib32
export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
export PATH=$ORACLE_HOME/JRE/bin:$ORACLE_HOME/bin:.:$PATH
export TEMPDIR=/tmp
export THREADS_FLAG=native
export PATH=$PATH:$ORACLE_HOME/bin:$ORACLE_HOME/oracm/bin
export CLASSPATH=$CLASSPATH:$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib:$ORACLE_HOME/network/jlib
export EDITOR=vi
export LANG=ko_KR.eucKR
export PATH ORACLE_BASE ORACLE_HOME ORACLE_OWNER ORACLE_SID  TNS_ADMIN NLS_LANG LD_LIBRARY_PATH ORA_NLS33  PATH LD_ASSUME_KERNEL TEMPDIR THREADS_FLAG PATH CLASSPATH EDITOR LANG NLS_DATE_FORMAT DISABLE_HUGETLBFS LDPATH


sqlplus -s kumc_cost/kumc_cost << __END__
	WHENEVER SQLERROR EXIT 1
	WHENEVER OSERROR EXIT 1
	SET TIMING ON
	SET SERVEROUTPUT ON
	SET PAGESIZE 0
	SET FEEDBACK OFF
	SET VERIFY OFF
	SET HEADING OFF
	SET ECHO OFF

	DECLARE
		vMsg	VARCHAR2(4000)	:= NULL;
		vSQL	VARCHAR2(4000)	:= NULL;
		vCheck	BOOLEAN			:= TRUE;
		vSeq	NUMBER;
	BEGIN
		DBMS_OUTPUT.ENABLE('10000000000');

		SELECT	cpi_seq
		INTO	vSeq
		FROM	COST_PROCESS_INFO
		WHERE	cpi_status = 'P';

		PROC_PROFIT_DIST(vCheck, vMsg);
		--vSQL := 'CALL PROC_PROFIT_DIST(:vCheck, :vMsg)';
		--EXECUTE IMMEDIATE vSQL USING IN vCheck, OUT vMsg;
		--DBMS_OUTPUT.PUT_LINE(vMsg);
		
		EXCEPTION
			WHEN NO_DATA_FOUND THEN
				DBMS_OUTPUT.PUT_LINE('진행중인 절차가 없습니다.!!');
	END;
	/
__END__


EXITCODE=$?
export EXITCODE

if [ "$EXITCODE" -ne 0 ]
then
	echo "Error: SQL*Plus exit code : $EXITCODE"
	echo ""
	echo "===== Procedure run aborted at `date` !!! ===="
	echo ""
	exit 1
fi

echo ""
echo "===== Procedure Finished at `date` !!! ===="
echo ""
블로그 이미지

유효하지않음

,

Introduction

Most users at one time or another have dealt with hierarchical data in a SQL database and no doubt learned that the management of hierarchical data is not what a relational database is intended for. The tables of a relational database are not hierarchical (like XML), but are simply a flat list. Hierarchical data has a parent-child relationship that is not naturally represented in a relational database table.

For our purposes, hierarchical data is a collection of data where each item has a single parent and zero or more children (with the exception of the root item, which has no parent). Hierarchical data can be found in a variety of database applications, including forum and mailing list threads, business organization charts, content management categories, and product categories. For our purposes we will use the following product category hierarchy from an fictional electronics store:

These categories form a hierarchy in much the same way as the other examples cited above. In this article we will examine two models for dealing with hierarchical data in MySQL, starting with the traditional adjacency list model.

The Adjacency List Model

Typically the example categories shown above will be stored in a table like the following (I'm including full CREATE and INSERT statements so you can follow along):

CREATE TABLE category(
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
parent INT DEFAULT NULL);


INSERT INTO category
VALUES(1,'ELECTRONICS',NULL),(2,'TELEVISIONS',1),(3,'TUBE',2),
(4,'LCD',2),(5,'PLASMA',2),(6,'PORTABLE ELECTRONICS',1),
(7,'MP3 PLAYERS',6),(8,'FLASH',7),
(9,'CD PLAYERS',6),(10,'2 WAY RADIOS',6);

SELECT * FROM category ORDER BY category_id;

+-------------+----------------------+--------+
| category_id | name                 | parent |
+-------------+----------------------+--------+
|           1 | ELECTRONICS          |   NULL |
|           2 | TELEVISIONS          |      1 |
|           3 | TUBE                 |      2 |
|           4 | LCD                  |      2 |
|           5 | PLASMA               |      2 |
|           6 | PORTABLE ELECTRONICS |      1 |
|           7 | MP3 PLAYERS          |      6 |
|           8 | FLASH                |      7 |
|           9 | CD PLAYERS           |      6 |
|          10 | 2 WAY RADIOS         |      6 |
+-------------+----------------------+--------+
10 rows in set (0.00 sec)

In the adjacency list model, each item in the table contains a pointer to its parent. The topmost element, in this case electronics, has a NULL value for its parent. The adjacency list model has the advantage of being quite simple, it is easy to see that FLASH is a child of mp3 players, which is a child of portable electronics, which is a child of electronics. While the adjacency list model can be dealt with fairly easily in client-side code, working with the model can be more problematic in pure SQL.

Retrieving a Full Tree

The first common task when dealing with hierarchical data is the display of the entire tree, usually with some form of indentation. The most common way of doing this is in pure SQL is through the use of a self-join:

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name = 'ELECTRONICS';

+-------------+----------------------+--------------+-------+
| lev1        | lev2                 | lev3         | lev4  |
+-------------+----------------------+--------------+-------+
| ELECTRONICS | TELEVISIONS          | TUBE         | NULL  |
| ELECTRONICS | TELEVISIONS          | LCD          | NULL  |
| ELECTRONICS | TELEVISIONS          | PLASMA       | NULL  |
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS  | FLASH |
| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS   | NULL  |
| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL  |
+-------------+----------------------+--------------+-------+
6 rows in set (0.00 sec)

Finding all the Leaf Nodes

We can find all the leaf nodes in our tree (those with no children) by using a LEFT JOIN query:

SELECT t1.name FROM
category AS t1 LEFT JOIN category as t2
ON t1.category_id = t2.parent
WHERE t2.category_id IS NULL;


+--------------+
| name         |
+--------------+
| TUBE         |
| LCD          |
| PLASMA       |
| FLASH        |
| CD PLAYERS   |
| 2 WAY RADIOS |
+--------------+

Retrieving a Single Path

The self-join also allows us to see the full path through our hierarchies:

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name = 'ELECTRONICS' AND t4.name = 'FLASH';

+-------------+----------------------+-------------+-------+
| lev1        | lev2                 | lev3        | lev4  |
+-------------+----------------------+-------------+-------+
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |
+-------------+----------------------+-------------+-------+
1 row in set (0.01 sec)

The main limitation of such an approach is that you need one self-join for every level in the hierarchy, and performance will naturally degrade with each level added as the joining grows in complexity.

Limitations of the Adjacency List Model

Working with the adjacency list model in pure SQL can be difficult at best. Before being able to see the full path of a category we have to know the level at which it resides. In addition, special care must be taken when deleting nodes because of the potential for orphaning an entire sub-tree in the process (delete the portable electronics category and all of its children are orphaned). Some of these limitations can be addressed through the use of client-side code or stored procedures. With a procedural language we can start at the bottom of the tree and iterate upwards to return the full tree or a single path. We can also use procedural programming to delete nodes without orphaning entire sub-trees by promoting one child element and re-ordering the remaining children to point to the new parent.

The Nested Set Model

What I would like to focus on in this article is a different approach, commonly referred to as the Nested Set Model. In the Nested Set Model, we can look at our hierarchy in a new way, not as nodes and lines, but as nested containers. Try picturing our electronics categories this way:

Notice how our hierarchy is still maintained, as parent categories envelop their children.We represent this form of hierarchy in a table through the use of left and right values to represent the nesting of our nodes:

CREATE TABLE nested_category (
 category_id INT AUTO_INCREMENT PRIMARY KEY,
 name VARCHAR(20) NOT NULL,
 lft INT NOT NULL,
 rgt INT NOT NULL
);


INSERT INTO nested_category
VALUES(1,'ELECTRONICS',1,20),(2,'TELEVISIONS',2,9),(3,'TUBE',3,4),
(4,'LCD',5,6),(5,'PLASMA',7,8),(6,'PORTABLE ELECTRONICS',10,19),
(7,'MP3 PLAYERS',11,14),(8,'FLASH',12,13),
(9,'CD PLAYERS',15,16),(10,'2 WAY RADIOS',17,18);


SELECT * FROM nested_category ORDER BY category_id;


+-------------+----------------------+-----+-----+
| category_id | name                 | lft | rgt |
+-------------+----------------------+-----+-----+
|           1 | ELECTRONICS          |   1 |  20 |
|           2 | TELEVISIONS          |   2 |   9 |
|           3 | TUBE                 |   3 |   4 |
|           4 | LCD                  |   5 |   6 |
|           5 | PLASMA               |   7 |   8 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |
|           7 | MP3 PLAYERS          |  11 |  14 |
|           8 | FLASH                |  12 |  13 |
|           9 | CD PLAYERS           |  15 |  16 |
|          10 | 2 WAY RADIOS         |  17 |  18 |
+-------------+----------------------+-----+-----+

We use lft and rgt because left and right are reserved words in MySQL, see http://dev.mysql.com/doc/mysql/en/reserved-words.html for the full list of reserved words.

So how do we determine left and right values? We start numbering at the leftmost side of the outer node and continue to the right:

This design can be applied to a typical tree as well:

When working with a tree, we work from left to right, one layer at a time, descending to each node's children before assigning a right-hand number and moving on to the right. This approach is called the modified preorder tree traversal algorithm.

Retrieving a Full Tree

We can retrieve the full tree through the use of a self-join that links parents with nodes on the basis that a node's lft value will always appear between its parent's lft and rgt values:

SELECT node.name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND parent.name = 'ELECTRONICS'
ORDER BY node.lft;


+----------------------+
| name                 |
+----------------------+
| ELECTRONICS          |
| TELEVISIONS          |
| TUBE                 |
| LCD                  |
| PLASMA               |
| PORTABLE ELECTRONICS |
| MP3 PLAYERS          |
| FLASH                |
| CD PLAYERS           |
| 2 WAY RADIOS         |
+----------------------+

Unlike our previous examples with the adjacency list model, this query will work regardless of the depth of the tree. We do not concern ourselves with the rgt value of the node in our BETWEEN clause because the rgt value will always fall within the same parent as the lft values.

Finding all the Leaf Nodes

Finding all leaf nodes in the nested set model even simpler than the LEFT JOIN method used in the adjacency list model. If you look at the nested_category table, you may notice that the lft and rgt values for leaf nodes are consecutive numbers. To find the leaf nodes, we look for nodes where rgt = lft + 1:

SELECT name
FROM nested_category
WHERE rgt = lft + 1;


+--------------+
| name         |
+--------------+
| TUBE         |
| LCD          |
| PLASMA       |
| FLASH        |
| CD PLAYERS   |
| 2 WAY RADIOS |
+--------------+

Retrieving a Single Path

With the nested set model, we can retrieve a single path without having multiple self-joins:

SELECT parent.name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'FLASH'
ORDER BY parent.lft;

+----------------------+
| name                 |
+----------------------+
| ELECTRONICS          |
| PORTABLE ELECTRONICS |
| MP3 PLAYERS          |
| FLASH                |
+----------------------+

Finding the Depth of the Nodes

We have already looked at how to show the entire tree, but what if we want to also show the depth of each node in the tree, to better identify how each node fits in the hierarchy? This can be done by adding a COUNT function and a GROUP BY clause to our existing query for showing the entire tree:

SELECT node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;

+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| ELECTRONICS          |     0 |
| TELEVISIONS          |     1 |
| TUBE                 |     2 |
| LCD                  |     2 |
| PLASMA               |     2 |
| PORTABLE ELECTRONICS |     1 |
| MP3 PLAYERS          |     2 |
| FLASH                |     3 |
| CD PLAYERS           |     2 |
| 2 WAY RADIOS         |     2 |
+----------------------+-------+

We can use the depth value to indent our category names with the CONCAT and REPEAT string functions:

SELECT CONCAT( REPEAT(' ', COUNT(parent.name) - 1), node.name) AS name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;

+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
+-----------------------+

Of course, in a client-side application you will be more likely to use the depth value directly to display your hierarchy. Web developers could loop through the tree, adding <li></li> and <ul></ul> tags as the depth number increases and decreases.

Depth of a Sub-Tree

When we need depth information for a sub-tree, we cannot limit either the node or parent tables in our self-join because it will corrupt our results. Instead, we add a third self-join, along with a sub-query to determine the depth that will be the new starting point for our sub-tree:

SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
	nested_category AS parent,
	nested_category AS sub_parent,
	(
		SELECT node.name, (COUNT(parent.name) - 1) AS depth
		FROM nested_category AS node,
		nested_category AS parent
		WHERE node.lft BETWEEN parent.lft AND parent.rgt
		AND node.name = 'PORTABLE ELECTRONICS'
		GROUP BY node.name
		ORDER BY node.lft
	)AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
	AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
	AND sub_parent.name = sub_tree.name
GROUP BY node.name
ORDER BY node.lft;


+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| PORTABLE ELECTRONICS |     0 |
| MP3 PLAYERS          |     1 |
| FLASH                |     2 |
| CD PLAYERS           |     1 |
| 2 WAY RADIOS         |     1 |
+----------------------+-------+

This function can be used with any node name, including the root node. The depth values are always relative to the named node.

Find the Immediate Subordinates of a Node

Imagine you are showing a category of electronics products on a retailer web site. When a user clicks on a category, you would want to show the products of that category, as well as list its immediate sub-categories, but not the entire tree of categories beneath it. For this, we need to show the node and its immediate sub-nodes, but no further down the tree. For example, when showing the PORTABLE ELECTRONICS category, we will want to show MP3 PLAYERS, CD PLAYERS, and 2 WAY RADIOS, but not FLASH.

This can be easily accomplished by adding a HAVING clause to our previous query:

SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
	nested_category AS parent,
	nested_category AS sub_parent,
	(
		SELECT node.name, (COUNT(parent.name) - 1) AS depth
		FROM nested_category AS node,
		nested_category AS parent
		WHERE node.lft BETWEEN parent.lft AND parent.rgt
		AND node.name = 'PORTABLE ELECTRONICS'
		GROUP BY node.name
		ORDER BY node.lft
	)AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
	AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
	AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth <= 1
ORDER BY node.lft;

+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| PORTABLE ELECTRONICS |     0 |
| MP3 PLAYERS          |     1 |
| CD PLAYERS           |     1 |
| 2 WAY RADIOS         |     1 |
+----------------------+-------+

If you do not wish to show the parent node, change the HAVING depth <= 1 line to HAVING depth = 1.

Aggregate Functions in a Nested Set

Let's add a table of products that we can use to demonstrate aggregate functions with:

CREATE TABLE product(
product_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(40),
category_id INT NOT NULL
);


INSERT INTO product(name, category_id) VALUES('20" TV',3),('36" TV',3),
('Super-LCD 42"',4),('Ultra-Plasma 62"',5),('Value Plasma 38"',5),
('Power-MP3 5gb',7),('Super-Player 1gb',8),('Porta CD',9),('CD To go!',9),
('Family Talk 360',10);

SELECT * FROM product;

+------------+-------------------+-------------+
| product_id | name              | category_id |
+------------+-------------------+-------------+
|          1 | 20" TV            |           3 |
|          2 | 36" TV            |           3 |
|          3 | Super-LCD 42"     |           4 |
|          4 | Ultra-Plasma 62"  |           5 |
|          5 | Value Plasma 38"  |           5 |
|          6 | Power-MP3 128mb   |           7 |
|          7 | Super-Shuffle 1gb |           8 |
|          8 | Porta CD          |           9 |
|          9 | CD To go!         |           9 |
|         10 | Family Talk 360   |          10 |
+------------+-------------------+-------------+

Now let's produce a query that can retrieve our category tree, along with a product count for each category:

SELECT parent.name, COUNT(product.name)
FROM nested_category AS node ,
nested_category AS parent,
product
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.category_id = product.category_id
GROUP BY parent.name
ORDER BY node.lft;


+----------------------+---------------------+
| name                 | COUNT(product.name) |
+----------------------+---------------------+
| ELECTRONICS          |                  10 |
| TELEVISIONS          |                   5 |
| TUBE                 |                   2 |
| LCD                  |                   1 |
| PLASMA               |                   2 |
| PORTABLE ELECTRONICS |                   5 |
| MP3 PLAYERS          |                   2 |
| FLASH                |                   1 |
| CD PLAYERS           |                   2 |
| 2 WAY RADIOS         |                   1 |
+----------------------+---------------------+

This is our typical whole tree query with a COUNT and GROUP BY added, along with a reference to the product table and a join between the node and product table in the WHERE clause. As you can see, there is a count for each category and the count of subcategories is reflected in the parent categories.

Adding New Nodes

Now that we have learned how to query our tree, we should take a look at how to update our tree by adding a new node. Let's look at our nested set diagram again:

If we wanted to add a new node between the TELEVISIONS and PORTABLE ELECTRONICS nodes, the new node would have lft and rgt values of 10 and 11, and all nodes to its right would have their lft and rgt values increased by two. We would then add the new node with the appropriate lft and rgt values. While this can be done with a stored procedure in MySQL 5, I will assume for the moment that most readers are using 4.1, as it is the latest stable version, and I will isolate my queries with a LOCK TABLES statement instead:

LOCK TABLE nested_category WRITE;


SELECT @myRight := rgt FROM nested_category
WHERE name = 'TELEVISIONS';



UPDATE nested_category SET rgt = rgt + 2 WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft + 2 WHERE lft > @myRight;

INSERT INTO nested_category(name, lft, rgt) VALUES('GAME CONSOLES', @myRight + 1, @myRight + 2);

UNLOCK TABLES;

We can then check our nesting with our indented tree query:

SELECT CONCAT( REPEAT( ' ', (COUNT(parent.name) - 1) ), node.name) AS name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;


+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  GAME CONSOLES        |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
+-----------------------+

If we instead want to add a node as a child of a node that has no existing children, we need to modify our procedure slightly. Let's add a new FRS node below the 2 WAY RADIOS node:

LOCK TABLE nested_category WRITE;

SELECT @myLeft := lft FROM nested_category

WHERE name = '2 WAY RADIOS';

UPDATE nested_category SET rgt = rgt + 2 WHERE rgt > @myLeft;
UPDATE nested_category SET lft = lft + 2 WHERE lft > @myLeft;

INSERT INTO nested_category(name, lft, rgt) VALUES('FRS', @myLeft + 1, @myLeft + 2);

UNLOCK TABLES;

In this example we expand everything to the right of the left-hand number of our proud new parent node, then place the node to the right of the left-hand value. As you can see, our new node is now properly nested:

SELECT CONCAT( REPEAT( ' ', (COUNT(parent.name) - 1) ), node.name) AS name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;


+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  GAME CONSOLES        |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+

Deleting Nodes

The last basic task involved in working with nested sets is the removal of nodes. The course of action you take when deleting a node depends on the node's position in the hierarchy; deleting leaf nodes is easier than deleting nodes with children because we have to handle the orphaned nodes.

When deleting a leaf node, the process if just the opposite of adding a new node, we delete the node and its width from every node to its right:

LOCK TABLE nested_category WRITE;


SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
WHERE name = 'GAME CONSOLES';


DELETE FROM nested_category WHERE lft BETWEEN @myLeft AND @myRight;


UPDATE nested_category SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft - @myWidth WHERE lft > @myRight;

UNLOCK TABLES;

And once again, we execute our indented tree query to confirm that our node has been deleted without corrupting the hierarchy:

SELECT CONCAT( REPEAT( ' ', (COUNT(parent.name) - 1) ), node.name) AS name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;


+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+

This approach works equally well to delete a node and all its children:

LOCK TABLE nested_category WRITE;


SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
WHERE name = 'MP3 PLAYERS';


DELETE FROM nested_category WHERE lft BETWEEN @myLeft AND @myRight;


UPDATE nested_category SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft - @myWidth WHERE lft > @myRight;

UNLOCK TABLES;

And once again, we query to see that we have successfully deleted an entire sub-tree:

SELECT CONCAT( REPEAT( ' ', (COUNT(parent.name) - 1) ), node.name) AS name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;


+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  PORTABLE ELECTRONICS |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+

The other scenario we have to deal with is the deletion of a parent node but not the children. In some cases you may wish to just change the name to a placeholder until a replacement is presented, such as when a supervisor is fired. In other cases, the child nodes should all be moved up to the level of the deleted parent:

LOCK TABLE nested_category WRITE;


SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
WHERE name = 'PORTABLE ELECTRONICS';


DELETE FROM nested_category WHERE lft = @myLeft;


UPDATE nested_category SET rgt = rgt - 1, lft = lft - 1 WHERE lft BETWEEN @myLeft AND @myRight;
UPDATE nested_category SET rgt = rgt - 2 WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft - 2 WHERE lft > @myRight;

UNLOCK TABLES;

In this case we subtract two from all elements to the right of the node (since without children it would have a width of two), and one from the nodes that are its children (to close the gap created by the loss of the parent's left value). Once again, we can confirm our elements have been promoted:

SELECT CONCAT( REPEAT( ' ', (COUNT(parent.name) - 1) ), node.name) AS name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;


+---------------+
| name          |
+---------------+
| ELECTRONICS   |
|  TELEVISIONS  |
|   TUBE        |
|   LCD         |
|   PLASMA      |
|  CD PLAYERS   |
|  2 WAY RADIOS |
|   FRS         |
+---------------+

Other scenarios when deleting nodes would include promoting one of the children to the parent position and moving the child nodes under a sibling of the parent node, but for the sake of space these scenarios will not be covered in this article.

Final Thoughts

While I hope the information within this article will be of use to you, the concept of nested sets in SQL has been around for over a decade, and there is a lot of additional information available in books and on the Internet. In my opinion the most comprehensive source of information on managing hierarchical information is a book called Joe Celko's Trees and Hierarchies in SQL for Smarties, written by a very respected author in the field of advanced SQL, Joe Celko. Joe Celko is often credited with the nested sets model and is by far the most prolific author on the subject. I have found Celko's book to be an invaluable resource in my own studies and highly recommend it. The book covers advanced topics which I have not covered in this article, and provides additional methods for managing hierarchical data in addition to the Adjacency List and Nested Set models.

In the References / Resources section that follows I have listed some web resources that may be of use in your research of managing hierarchal data, including a pair of PHP related resources that include pre-built PHP libraries for handling nested sets in MySQL. Those of you who currently use the adjacency list model and would like to experiment with the nested set model will find sample code for converting between the two in the Storing Hierarchical Data in a Database resource listed below.


블로그 이미지

유효하지않음

,

[출처] http://kldp.org/node/103288

Fedora 10 패키지 목록을 살펴보던 중 호기심을 자극하는 패키지가 하나 있었다. 뭔가하고 살펴보니 ext3 파일 시스템에서 지워진 파일의 복구를 해주는 놈이다.

ext2와 다른 특성으로 인해 ext3에서 지워진 파일의 복구는 꽤 어려운 명령어들을 알아야했고 복구율도 좋지 않았었다. 하지만 ext3grep은 이러한 생각을 바꾸게 만들기에 충분했다.

소스 다운로드는 http://code.google.com/p/ext3grep/ 에서 할 수 있고 Fedora나 Debian의 최신 버전에는 포함되어 있으니 해당 배포판의 패키지 관리자로 설치하면 된다.

설치를 하고 간단한 테스트를 해보았다. 시간상 1GB정도의 파티션을 만들고 테스트를 진행했다.

    # mkfs.ext3 /dev/sdb1
    # mount /dev/sdb1 /mnt/test/
    # df -h
    /dev/sdb1             966M   18M  899M   2% /mnt/test

몇개의 디렉토리와 파일을 만들었다.

    # ls *
    test1.txt  test2.txt  테스트.txt  테스트2.txt

    dir1:
    dir1.txt

    dir2:
    dir2.txt

    dir3:
    dir3.txt

    lost+found:

    디렉토리1:
    디렉토리1.txt

    디렉토리2:
    디렉토리2.txt

    디렉토리3:
    디렉토리3.txt


그 중에 몇개를 삭제했다.

# rm -rf dir2 dir3 test2.txt 디렉토리1 디렉토리3 테스트.txt


이제 unmount 하고 실제 ext3grep 을 사용할 차례다.

    # umount /mnt/test


–dump-names 로 경로를 포함한 파일들의 경로를 알 수 있다.

    # ext3grep –dump-names /dev/sdb1
    Running ext3grep version 0.10.1
    Number of groups: 8
    Minimum / maximum journal block: 562 / 4664
    Loading journal descriptors… sorting… done
    The oldest inode block that is still in the journal, appears to be from 1235694214 = Fri Feb 27 09:23:34 2009
    Number of descriptors in journal: 269; min / max sequence numbers: 2 / 40
    Finding all blocks that might be directories.
    D: block containing directory start, d: block containing more directory entries.
    Each plus represents a directory start that references the same inode as a directory start that we found previously.

    Searching group 0: DDD+DD+++++++++++++++++D+DD+++++++++
    Searching group 1: +
    Searching group 2: +
    Searching group 3: +
    Searching group 4: +
    Searching group 5: +
    Searching group 6: +
    Searching group 7:
    Writing analysis so far to ’sdb1.ext3grep.stage1′. Delete that file if you want to do this stage again.
    Result of stage one:
    8 inodes are referenced by one or more directory blocks, 4 of those inodes are still allocated.
    7 inodes are referenced by more than one directory block, 3 of those inodes are still allocated.
    0 blocks contain an extended directory.
    Result of stage two:
    4 of those inodes could be resolved because they are still allocated.
    4 inodes could be resolved because all refering blocks but one were journal blocks.
    All directory inodes are accounted for!

    Writing analysis so far to ’sdb1.ext3grep.stage2′. Delete that file if you want to do this stage again.
    dir1
    dir1/.dir1.txt.swp
    dir1/dir1.txt
    dir2
    dir2/.dir2.txt.swp
    dir2/dir2.txt
    dir3
    dir3/.dir3.txt.swp
    dir3/dir3.txt
    lost+found
    test1.txt
    test2.txt
    디렉토리1
    디렉토리1/.디렉토리1.txt.swp
    디렉토리1/디렉토리1.txt
    디렉토리2
    디렉토리2/.디렉토리2.txt.swp
    디렉토리2/디렉토리2.txt
    디렉토리3
    디렉토리3/.디렉토리3.txt.swp
    디렉토리3/디렉토리3.txt
    테스트.txt
    테스트2.txt


위 명령어를 실행한 후 ext3grep.stage1, ext3grep.stage2 파일이 생성되는데 inode와 block의 정보를 담고 있다. 한번 생성되면 다른 명령어를 실행할때 재사용되기 때문에 검색에 소요되는 시간이 줄어든다.

    # cat sdb1.ext3grep.stage1
    # Stage 1 data for /dev/sdb1.
    # Inodes and directory start blocks that use it for dir entry ‘.’.
    # INODE : BLOCK [BLOCK ...]
    2 : 556 573 597 605 610 682 688 698 703 713 719 732 859
    11 : 557
    15713 : 740 792 800 805 40960
    31425 : 582 659 666 671 79872
    47137 : 571 620 628 633 112640
    62849 : 578 645 651 145408
    78561 : 736 774 780 172032
    94273 : 730 749 757 762 204800
    # Extended directory blocks.
    # END

    # cat sdb1.ext3grep.stage2
    # Stage 2 data for /dev/sdb1.
    # Inodes path and directory blocks.
    # INODE PATH BLOCK [BLOCK ...]
    2 ” 556
    11 ‘lost+found’ 557
    15713 ‘디렉토리3′ 40960
    31425 ‘dir3′ 79872
    47137 ‘dir1′ 112640
    62849 ‘dir2′ 145408
    78561 ‘디렉토리2′ 172032
    94273 ‘디렉토리1′ 204800
    # END


–restore-all 은 해당 장치의 모든 파일을 명령어가 실행된 위치에 RESTORED_FILES라는 디렉토리를 생성하고 그 안에 복구해준다. 명령어를 실행하기 전에 충분한 공간이 있는지 확인하자.

    # ext3grep –restore-all /dev/sdb1
    Running ext3grep version 0.10.1
    Number of groups: 8
    Minimum / maximum journal block: 562 / 4664
    Loading journal descriptors… sorting… done
    The oldest inode block that is still in the journal, appears to be from 1235694214 = Fri Feb 27 09:23:34 2009
    Number of descriptors in journal: 269; min / max sequence numbers: 2 / 40
    Writing output to directory RESTORED_FILES/
    Finding all blocks that might be directories.
    D: block containing directory start, d: block containing more directory entries.
    Each plus represents a directory start that references the same inode as a directory start that we found previously.

    Searching group 0: DDD+DD+++++++++++++++++D+DD+++++++++
    Searching group 1: +
    Searching group 2: +
    Searching group 3: +
    Searching group 4: +
    Searching group 5: +
    Searching group 6: +
    Searching group 7:
    Writing analysis so far to ’sdb1.ext3grep.stage1′. Delete that file if you want to do this stage again.
    Result of stage one:
    8 inodes are referenced by one or more directory blocks, 4 of those inodes are still allocated.
    7 inodes are referenced by more than one directory block, 3 of those inodes are still allocated.
    0 blocks contain an extended directory.
    Result of stage two:
    4 of those inodes could be resolved because they are still allocated.
    4 inodes could be resolved because all refering blocks but one were journal blocks.
    All directory inodes are accounted for!

    Writing analysis so far to ’sdb1.ext3grep.stage2′. Delete that file if you want to do this stage again.
    Restoring dir1/.dir1.txt.swp
    Restoring dir1/dir1.txt
    Restoring dir2/.dir2.txt.swp
    Restoring dir2/dir2.txt
    Restoring dir3/.dir3.txt.swp
    Restoring dir3/dir3.txt
    Restoring test1.txt
    Restoring test2.txt
    Restoring 디렉토리1/.디렉토리1.txt.swp
    Restoring 디렉토리1/디렉토리1.txt
    Restoring 디렉토리2/.디렉토리2.txt.swp
    Restoring 디렉토리2/디렉토리2.txt
    Restoring 디렉토리3/.디렉토리3.txt.swp
    Restoring 디렉토리3/디렉토리3.txt
    Restoring 테스트.txt
    Restoring 테스트2.txt

    # cd RESTORED_FILES/

    # ls *
    test1.txt  test2.txt  테스트.txt  테스트2.txt

    dir1:
    dir1.txt

    dir2:
    dir2.txt

    dir3:
    dir3.txt

    lost+found:

    디렉토리1:
    디렉토리1.txt

    디렉토리2:
    디렉토리2.txt

    디렉토리3:
    디렉토리3.txt


–restore-all 명령어와 함께 사용할 수 있는 필터가 여러개 있는데 –after 옵션을 주면 그 시간 이후의 파일들만 복구해준다. unix time을 적어주면 된다.

    # ext3grep –restore-all –after=1235694514 /dev/sdb1
    Running ext3grep version 0.10.1
    Only show/process deleted entries if they are deleted on or after Fri Feb 27 09:28:34 2009.

    Number of groups: 8
    Minimum / maximum journal block: 562 / 4664
    Loading journal descriptors… sorting… done
    The oldest inode block that is still in the journal, appears to be from 1235694214 = Fri Feb 27 09:23:34 2009
    Number of descriptors in journal: 269; min / max sequence numbers: 2 / 40
    Loading sdb1.ext3grep.stage2… done
    Not undeleting “dir1/.dir1.txt.swp” because it was deleted before 1235694514 (32767)
    Restoring dir1/dir1.txt
    Not undeleting “dir2/.dir2.txt.swp” because it was deleted before 1235694514 (1235694303)
    Not undeleting “dir2/dir2.txt” because it was deleted before 1235694514 (1235694303)
    Not undeleting “dir3/.dir3.txt.swp” because it was deleted before 1235694514 (1235694303)
    Not undeleting “dir3/dir3.txt” because it was deleted before 1235694514 (1235694303)
    Restoring test1.txt
    Not undeleting “test2.txt” because it was deleted before 1235694514 (1235694287)
    Not undeleting “디렉토리1/.디렉토리1.txt.swp” because it was deleted before 1235694514 (1235694287)
    Not undeleting “디렉토리1/디렉토리1.txt” because it was deleted before 1235694514 (1235694287)
    Not undeleting “디렉토리2/.디렉토리2.txt.swp” because it was deleted before 1235694514 (1235694287)
    Restoring 디렉토리2/디렉토리2.txt
    Not undeleting “디렉토리3/.디렉토리3.txt.swp” because it was deleted before 1235694514 (1235694404)
    Not undeleting “디렉토리3/디렉토리3.txt” because it was deleted before 1235694514 (1235694404)
    Not undeleting “테스트.txt” because it was deleted before 1235694514 (1235694404)
    Restoring 테스트2.txt


특정 이름의 파일만 복구 하려면 –restore-file 다음에 파일명을 써주면 된다.

    # ext3grep –restore-file 테스트.txt /dev/sdb1
    Running ext3grep version 0.10.1
    Number of groups: 8
    Minimum / maximum journal block: 562 / 4664
    Loading journal descriptors… sorting… done
    The oldest inode block that is still in the journal, appears to be from 1235694214 = Fri Feb 27 09:23:34 2009
    Number of descriptors in journal: 269; min / max sequence numbers: 2 / 40
    Writing output to directory RESTORED_FILES/
    Loading sdb1.ext3grep.stage2… done
    Restoring 테스트.txt

    # cd RESTORED_FILES/
    # ls
    테스트.txt


디렉토리 밑에 있는 파일이라면 경로까지 정확하게 써주면 된다. 경로를 포함한 파일명은 위에서 한번 실행했던 –dump-names로 알 수 있다.

    # ext3grep –restore-file dir2/dir2.txt /dev/sdb1
    Running ext3grep version 0.10.1
    Number of groups: 8
    Minimum / maximum journal block: 562 / 4664
    Loading journal descriptors… sorting… done
    The oldest inode block that is still in the journal, appears to be from 1235694214 = Fri Feb 27 09:23:34 2009
    Number of descriptors in journal: 269; min / max sequence numbers: 2 / 40
    Loading sdb1.ext3grep.stage2… done
    Restoring dir2/dir2.txt


더 많은 옵션이 있지만 일반적인 사용자라면 이정도만 알아도 충분히 복구할 수 있을 것이다. 이름처럼 ext3에 대해서 복구를 해주기 때문에 포맷이 되었거나 다른 파일시스템에서는 복구가 안된다.

마지막으로 노파심에서 한마디 하자면 실수로 파일을 삭제했을때에는 최대한 빨리 해당 장치를 unmount 해서 덮어써지지 않게 해야한다.

자세한 정보는 저자의 홈페이지에서 확인하자.

블로그 이미지

유효하지않음

,