Wednesday, September 30, 2009

[Oracle] Update시 WHERE 조건에서 SELECT할 수 있을까요?

[Oracle] Update시 WHERE 조건에서 SELECT할 수 있을까요?
원문 : Update시 WHERE 조건에서 SELECT할 수 있을까요?

이것은 내가 DSN에 질문한 것이다.

Update시 WHERE 조건에서 SELECT할 수 있을까요?

Oracle 9i 입니다.


테이블 TA와 TB가 있습니다. TA와 TB에는 모두 동일한 컬럼 C1, C2가 있습니다.

그리고 TA의 C0를 일정한 값 '0000' 으로 업데이트하려고 합니다.

헌데 조건이 있습니다. TA.C1과 TA.C2가 TB.C1, TB.C2와 같아야 하며, TB의 TB.C1 과 TB.C2를 가져오는 조건이 또 따로 있습니다.

즉, UPDATE의 SET 에서 TB에 있는 컬럼의 값을 사용하는 것이 아닙니다.

현재 제가하는 방법을 보여드리면,

SPOOL updatequery.sql

SELECT 'UPDATE TA SET C0=''0000'' WHERE C1='''||TB.C1||''' C2='''||TB.C2||''';'

FROM TA, TB

WHERE TA.C1=TB.C2 AND TA.C2=TB.C2

AND TB와 관련된 조건들...;

SPOOL OFF

뭐 이런식으로 해서 UPDATE 문장들을 뽑아낸다음에 다시 그걸 sqlplus @updatequery.sql 로 실행하고 COMMIT;합니다.
아무리봐도 뭔가 한방에 처리할 수 있는 방법이 있을 것 같은데요...
대체 이찌해야할까요?

도움 부탁드립니다.


감사합니다.
이 글에 대한 댓글이 총 4건 있습니다.

select ... for update ... 라는 쿼리가 있습니다..

select 후 자동으로 lock 을 걸고 update 합니다...

단일테이블에서 select 와 update 를 동시에 가능하게 하는 쿼리입니다.
이경환(babocom)님이 2005-09-20 16:18:25에 작성한 댓글입니다.
이 댓글은 2005-09-20 16:20:53에 마지막으로 수정되었습니다.

UPDATE ta a
SET a.c0 = '0000'
WHERE (a.c1, a.c2) IN (SELECT b.c1, b.c2
FROM tb b
WHERE b.c1 = a.c1 AND b.c2 = a.c2 and TB와 관련된 조건들 ... )
장진주(zozogirl)님이 2005-09-20 16:57:48에 작성한 댓글입니다.

바로 윗분의 문장과 같은 의미지만..

TA의 C1과 C2가 PK라면..

아래와 같은 문장도 가능합니다..

장점은 조인되는 테이블의 컬럼을 사용할 수 있다는 거죠..

또한 유리한 조건을 가진 테이블을 드라이브하기가 용이하겠죠..

수정가능한 조인뷰와 같은 이치입니다..

UPDATE (
SELECT TA.C1 C1
,TA.C2 C2
,TA.C0 C0
FROM TA, TB
WHERE TA.C1 = TB.C1
AND TA.C2 = TB.C2
AND TB와 관련된 조건들...
)
SET C0 = '0000'

M님이 2005-09-20 17:14:15에 작성한 댓글입니다.
이 댓글은 2005-09-20 17:15:31에 마지막으로 수정되었습니다. Edit X

감사합니다.

장진주(zozogirl)님의 손쉽게 쿼리로 해결하였습니다.

다른분들의 힌트도 새로운걸 알게 해주었습니다.

모두 큰도움이 되었습니다.

SELECT .. for UPDATE 같은 경우에는 이걸 찾아보느라 Expert One on One Oracle을 뒤져봤는데, 번역판은 색인이 잘안돼서 못찾고 원서를 찾아보니 색인에 바로 나오더군요..

흠.. 번역할때 색인도 모범적으로 따라줬으면 좋겠구만..

권남님이 2005-09-20 20:37:48에 작성한 댓글입니다. Edit X

SELECT된 값 바로 INSERT, UPDATE 하기

SELECT 된문 UPDATE 하기



UPDATE A
SET A.ATTEND_rsn1 = '1'
FROM LMS_ATTEND A, LMS_USER_PARTY B
WHERE A.YEAR_CD = '2008'
AND A.MONTH_CD = '2'
AND A.STUDENT_ID = B.USER_ID
AND A.PARTY_SEQ = B.PARTY_SEQ
AND B.FLAG = 'A'
AND A.STUDENT_ID IN( SELECT USER_ID

FROM LMS_USER

WHERE ACADEMY_CD = '10003'

AND DEL_YN <> 'Y' )


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



SELECT 된문 INSERT 하기



INSERT INTO EMPS( EMPNO, ENAME, SAL , DEPTNO)
SELECT EMPNO, ENAME, SAL , DEPTNO
FROM EMP
WHERE DEPTNO=10

svn 다음은 git 깃?

테크 트렌드
http://www.okjsp.pe.kr/seq/143088 kenu
2009-09-25 16:07:12.0
http://www.okjsp.pe.kr
svn 다음은 git 깃?
---
서브버전 다음으로 EGit(http://www.eclipse.org/egit/) 이 준비되고 있습니다. eclipse git client plugin이죠. svn과의 차이점은 중앙 저장소와 로컬 저장소가 분리되서 운영이 되는 약간 복잡한 구조입니다만, 배포 시점에 대한 커밋 타이밍 이슈를 해결하기 위한 방식인 것으로 알고 있습니다.
http://eclipsesource.com/blogs/2009/09/22/git-at-eclipse/

svn을 git으로 전환해야하는 이유에 대한 글도 있습니다.

•the free Pro Git book
•Why you should switch from SVN to Git
•http://whygitisbetterthanx.com/
기술 따라가기 힘드시죠. ^^; 군대에서 귀에 못이 박히게 듣던 소리가 생각납니다. "피할 수 없다면 즐겨라"

Tuesday, September 29, 2009

MySQL Dump 이용 DB서버이전

http://kin.naver.com/detail/detail.php?d1id=1&dir_id=108&docid=1098960&qb=amF2YXguc2VydmxldC5TZXJ2bGV0RXhjZXB0aW9uOiBFcnJvciBpbnN0YW50aWF0aW5nIHNlcnZsZXQgY2xhc3Mgb3JnLmFwYWNoZS5qYXNwZXIuc2VydmxldC5Kc3BTZXJ2bA==&enc=utf8&pid=fVcG2loi5TlsstAdAL0sss--485500&sid=SsH42lPNwUoAAEiZb3c

MySQL Dump 이용 DB서버이전

MySQL Dump 이용 DB서버이전

sweety2407 2008.09.30 19:48

조회 2,578

* 본 블로그의 OS환경은 윈도우->리눅스 서버로 원격접속하여 모든 작업을 수행합니다.

* 덤프뜨는 방법은 여러가지 방법이 있겠지만

처음 하시는 분들이 가장 이해하기 쉬울거 같은(?) 방법으로 진행하겠습니다.

* 기존서버 A와 이전할 서버 B가있다는 가정아래 진행합니다.

* A서버와 B서버의 mysql버전은 4.1.21로 테스트된 내용입니다.

* 모든 경로는 절대경로로 작업하겠습니다.

* A서버와 B서버 모두 외부FTP(알FTP..등)접속이 가능한 서버이어야

본 블로그의 내용대로 작업하실 수 있습니다.

물론 다른 방법도 있습니다.

*-A서버 작업시작-*

가. Telnet 혹은 SSH로 A서버에 원격접속합니다. (원격접속방법은 본 블로그를 찾아보세요.)

나. A서버의 mysql설치경로 찾아가기

cd /usr/local/mysql/bin [엔터]

다. ls [엔터] mssqldump라는 파일(이놈이 dump의 핵심)이 있는지 확인.

라. /usr/local/mysql/bin/mysqldump -u root -p DB명 > 생성할 덤프파일명.sql [엔터]

마. 덤프뜰 A서버 SQL패스워드를 입력하고 [엔터] 잠시 대기..

바. A서버 덤프뜨기 완료.

사. ls [엔터] 생성한 덤프파일명.sql이 보이는지 확인.

아. 생성한 덤프파일을 A서버의 FTP홈디렉토리경로로 복사한다.

cp -r 생성한 덤프파일명.sql FTP홈디렉토리경로 [엔터]

참고로 보통의 경우 FTP홈디렉토리는 /home/FTP접속계정/으로 되어있다.

자. FTP홈디렉토리로 이동

cd /home/A서버 FTP접속계정 [엔터]

차. ls [엔터] 생성한 덤프파일이 정상적으로 복사되었는지 확인.

카. 알FTP를 실행하여 A서버 접속 후 생성한 덤프파일 내컴퓨터로 다운로드.

*-A서버 작업끝-*

*-B서버 작업시작-*

가. 알FTP실행하여 B서버 접속 후 다운로드 받은 덤프파일을 B서버에 업로드.

나. Telnet 혹은 SSH로 B서버에 원격접속합니다. (원격접속방법은 본 블로그를 찾아보세요.)

다. FTP홈디렉토리로 이동

cd /home/B서버 FTP접속계정 [엔터]

라. ls [엔터] 업로드한 덤프파일.sql이 보이는지 확인.

마. 업로드한 덤프파일을 B서버의 mysql설치경로로 이동한다.

cp -r 업로드한 덤프파일.sql /usr/local/mysql/bin [엔터]

아. mysql 설치경로를 찾아가기

cd /usr/local/mysql/bin [엔터]

자. ls [엔터] 파일복사가 제대로 됬는지 확인.

차. 덤프 밀어넣기

/usr/local/mysql/bin/mysql -u root -p 밀어넣을 B서버DB명 < 업로드한 덤프파일명.sql [엔터]

카. 밀어넣을 B서버 SQL패스워드를 입력하고 [엔터] 잠시 대기..

타. 덤프 밀어넣기 완료.

*-B서버 작업끝-*

-*기타 참고정보-*

1. 덤프뜨기
mysqldump -u 사용자계정 -p 데이터베이스명 테이블명 > 저장될 파일명
예) mysqldump -u root -p mydb_name > mydb_name.sql
이렇게 하면 mydb_name을 모두 덤프를 뜨게된다.

테이블만 덤프를 뜨고 싶다면
예) mysqldump -u root -p mydb_name member > mydb_name.member.sql
이렇게 하면 원하는 테이블만 덤프를 뜰 수 있다.
2. 복구하기
mysql -u 사용자계정 -p DB명 < 덤프파일명
예) mysql -u root -p < 덤프파일명.sql
예) mysql -u root -p mydb_name < 덤프파일명.테이블명.sql

1.특정 db의 특정 table에서 원하는 값만 덤프받기
>> edu라는 디비에 a,b,c라는 테이블이 있다.

여기서 a라는 테이블에서 no가 7번이상이고 10번
이하인 값만 덤프를 받고자 한다. 어떻게 하겠는가?
여기서 사용되는 옵션은 -w 이다.그럼 위 질문의 sql문은 아래와 같다

mysqldump -u mysql_admin -p edu a -w'no=>7 and no=<10'> edu_a_cond.sql

위와같이 하면 no가 7~10번까지가 덤프될것이다.
위에서 조건문은 -w 다음에 싱글쿼테이션으로 묶어준다.

sql에서 사용하는 조건문이 다 될듯싶다.

모두 테스트를 해보진 않았다.

2.디비 스키마(Schema)만 백업받기
>>초기에 작성해 놓은 테이블 스키마가 없을때 어떻게 하겠는가?
만약 하나의 테이블이라면 desc 해서 일일이 다 삽질을 하면 되것지만

만약 테이블이 100개라면 ..크억...이럴때 사용하는 mysqldump옵션이 있습니다.
-d 입니다.

!.edu라는 디비의 모든 테이블 스키마를 백업받으려면
mysqldump -u mysql_admin -p -d edu > edu_db.sql

!.edu라는 디비의 a라는 테이블 스키마를 백업받으려면
mysqldump -u mysql_admin -p -d edu a> edu_a_table.sql

[Option Information]

--opt
[--quick --add-locks --add-drop-table --extended-insert]
원복을 할때 기존 DB와 TABLE, DATA를 삭제하고 백업한 내용으로 Update를 합니다.

-q, --quick
버퍼를 사용하지 않고 바로 표준출력으로 보낸다.

--add-locks
테이블의 덤프하기전에 해당 테이블을 잠그고 덤프한 후에 테이블을 풀어준다.

--add-drop-table
덤프 결과에서 create table 앞에 drop table 절을 추가한다.

-c, --complte-insert
INSERT 구문에서 필드명을 포함한 전체를 덤프

--extended-insert
INSERT문 하나에서 모든 레코드를 삽입하는 INSERT문을 생성합니다.

-f, --force
덤프 중 에러가 있어도 계속 진행

-h, --host
특정 호스트의 MySQL 에서 데이터 덤프

-t, --no-create-info
테이블 생성 정보는 덤프하지 않음(데이터만 덤프)

-d, --no-data
테이블 스키마만 덤프

--default-character-set=euckr
character set 지정

--extended-insert=FALSE
분리된 query문으로 작성

출처 : [직접 서술] 블로그 집필 - Now the temperature's changed

신고

의견 쓰기

sweety2407 2008.09.30 19:48
조회 2,578


* 본 블로그의 OS환경은 윈도우->리눅스 서버로 원격접속하여 모든 작업을 수행합니다.

* 덤프뜨는 방법은 여러가지 방법이 있겠지만

처음 하시는 분들이 가장 이해하기 쉬울거 같은(?) 방법으로 진행하겠습니다.

* 기존서버 A와 이전할 서버 B가있다는 가정아래 진행합니다.

* A서버와 B서버의 mysql버전은 4.1.21로 테스트된 내용입니다.

* 모든 경로는 절대경로로 작업하겠습니다.

* A서버와 B서버 모두 외부FTP(알FTP..등)접속이 가능한 서버이어야

본 블로그의 내용대로 작업하실 수 있습니다.

물론 다른 방법도 있습니다.



*-A서버 작업시작-*

가. Telnet 혹은 SSH로 A서버에 원격접속합니다. (원격접속방법은 본 블로그를 찾아보세요.)

나. A서버의 mysql설치경로 찾아가기

cd /usr/local/mysql/bin [엔터]

다. ls [엔터] mssqldump라는 파일(이놈이 dump의 핵심)이 있는지 확인.

라. /usr/local/mysql/bin/mysqldump -u root -p DB명 > 생성할 덤프파일명.sql [엔터]

마. 덤프뜰 A서버 SQL패스워드를 입력하고 [엔터] 잠시 대기..

바. A서버 덤프뜨기 완료.

사. ls [엔터] 생성한 덤프파일명.sql이 보이는지 확인.

아. 생성한 덤프파일을 A서버의 FTP홈디렉토리경로로 복사한다.

cp -r 생성한 덤프파일명.sql FTP홈디렉토리경로 [엔터]

참고로 보통의 경우 FTP홈디렉토리는 /home/FTP접속계정/으로 되어있다.

자. FTP홈디렉토리로 이동

cd /home/A서버 FTP접속계정 [엔터]

차. ls [엔터] 생성한 덤프파일이 정상적으로 복사되었는지 확인.

카. 알FTP를 실행하여 A서버 접속 후 생성한 덤프파일 내컴퓨터로 다운로드.

*-A서버 작업끝-*



*-B서버 작업시작-*

가. 알FTP실행하여 B서버 접속 후 다운로드 받은 덤프파일을 B서버에 업로드.

나. Telnet 혹은 SSH로 B서버에 원격접속합니다. (원격접속방법은 본 블로그를 찾아보세요.)

다. FTP홈디렉토리로 이동

cd /home/B서버 FTP접속계정 [엔터]

라. ls [엔터] 업로드한 덤프파일.sql이 보이는지 확인.

마. 업로드한 덤프파일을 B서버의 mysql설치경로로 이동한다.

cp -r 업로드한 덤프파일.sql /usr/local/mysql/bin [엔터]

아. mysql 설치경로를 찾아가기

cd /usr/local/mysql/bin [엔터]

자. ls [엔터] 파일복사가 제대로 됬는지 확인.

차. 덤프 밀어넣기

/usr/local/mysql/bin/mysql -u root -p 밀어넣을 B서버DB명 < 업로드한 덤프파일명.sql [엔터] 카. 밀어넣을 B서버 SQL패스워드를 입력하고 [엔터] 잠시 대기.. 타. 덤프 밀어넣기 완료. *-B서버 작업끝-* -*기타 참고정보-* 1. 덤프뜨기 mysqldump -u 사용자계정 -p 데이터베이스명 테이블명 > 저장될 파일명
예) mysqldump -u root -p mydb_name > mydb_name.sql
이렇게 하면 mydb_name을 모두 덤프를 뜨게된다.

테이블만 덤프를 뜨고 싶다면
예) mysqldump -u root -p mydb_name member > mydb_name.member.sql
이렇게 하면 원하는 테이블만 덤프를 뜰 수 있다.
2. 복구하기
mysql -u 사용자계정 -p DB명 < 덤프파일명 예) mysql -u root -p < 덤프파일명.sql 예) mysql -u root -p mydb_name < 덤프파일명.테이블명.sql 1.특정 db의 특정 table에서 원하는 값만 덤프받기 >> edu라는 디비에 a,b,c라는 테이블이 있다.

여기서 a라는 테이블에서 no가 7번이상이고 10번
이하인 값만 덤프를 받고자 한다. 어떻게 하겠는가?
여기서 사용되는 옵션은 -w 이다.그럼 위 질문의 sql문은 아래와 같다


mysqldump -u mysql_admin -p edu a -w'no=>7 and no=<10'> edu_a_cond.sql

위와같이 하면 no가 7~10번까지가 덤프될것이다.
위에서 조건문은 -w 다음에 싱글쿼테이션으로 묶어준다.

sql에서 사용하는 조건문이 다 될듯싶다.

모두 테스트를 해보진 않았다.

2.디비 스키마(Schema)만 백업받기
>>초기에 작성해 놓은 테이블 스키마가 없을때 어떻게 하겠는가?
만약 하나의 테이블이라면 desc 해서 일일이 다 삽질을 하면 되것지만

만약 테이블이 100개라면 ..크억...이럴때 사용하는 mysqldump옵션이 있습니다.
-d 입니다.

!.edu라는 디비의 모든 테이블 스키마를 백업받으려면
mysqldump -u mysql_admin -p -d edu > edu_db.sql

!.edu라는 디비의 a라는 테이블 스키마를 백업받으려면
mysqldump -u mysql_admin -p -d edu a> edu_a_table.sql



[Option Information]

--opt
[--quick --add-locks --add-drop-table --extended-insert]
원복을 할때 기존 DB와 TABLE, DATA를 삭제하고 백업한 내용으로 Update를 합니다.

-q, --quick
버퍼를 사용하지 않고 바로 표준출력으로 보낸다.

--add-locks
테이블의 덤프하기전에 해당 테이블을 잠그고 덤프한 후에 테이블을 풀어준다.

--add-drop-table
덤프 결과에서 create table 앞에 drop table 절을 추가한다.

-c, --complte-insert
INSERT 구문에서 필드명을 포함한 전체를 덤프

--extended-insert
INSERT문 하나에서 모든 레코드를 삽입하는 INSERT문을 생성합니다.

-f, --force
덤프 중 에러가 있어도 계속 진행

-h, --host
특정 호스트의 MySQL 에서 데이터 덤프

-t, --no-create-info
테이블 생성 정보는 덤프하지 않음(데이터만 덤프)

-d, --no-data
테이블 스키마만 덤프

--default-character-set=euckr
character set 지정

--extended-insert=FALSE
분리된 query문으로 작성

출처 : [직접 서술] 블로그 집필 - Now the temperature's changed

신고

의견 쓰기