'SQL'에 해당되는 글 15

  1. 2011.05.21 정렬 순서 지정하기
  2. 2010.09.06 순번 구하기
  3. 2010.07.04 데이터베이스 문제점 파악 방법
  4. 2010.06.30 NULL 주의
  5. 2010.01.15 CASE 구문내에 SELECT 사용하기
  6. 2009.12.24 쿼리문에서 홑따옴표
  7. 2009.05.13 일련번호중 비어 있는 값 찾아내기
  8. 2009.05.08 행 만들기
  9. 2009.05.07 유무를 판단하는 여러 방법
  10. 2009.04.28 [비교] UPDATE
  11. 2009.04.27 임시 테이블
  12. 2009.04.27 소계, 합계 처리
  13. 2009.04.18 좋은 코딩 습관 - 리턴값 확인
  14. 2009.03.19 변경 쿼리문 실행시 반드시 트랜잭션 걸 것! /////운영팁, 쿼리문에 변경할 데이터 조건에 거는거
  15. 2009.02.28 문자열 함수

정렬 순서 지정하기

item_cd 에 유효하지 않은 0이라는 값이 들어간 데이터가 있는데 제일 뒤로 빼서 정렬하고 싶다.

1. 데이터를 가져오는 쿼리를 분리하고 UNION 으로 합친다.
 ITEM_NM  ITEM_CD  ORD
 A01  101  0
 A05  250  0
 A09  200  0
 A03  0  1

2. ORDER BY 절에 CASE 구문으로 처리한다.(오라클에서는 decode 함수를 사용할수도 있다)
 ITEM_NM  ITEM_CD
 A01  101
 A09  200
 A05  250
 A03  0

순번 구하기

TB_DATA에 pk1, pk2, pk_old 가 기본키로 존재했음.
pk_old는 중복된 값이 들어올 수 있어서 pk_new 가 새로운 키로 들어와서 pk_old와 교체해야 하는 상황이 생겼음.
pk_new는 순번이다.

pk_new를 추가하고 기존 기본키를 삭제.
pk_new는 데이터가 들어가 있지 않으므로 순번을 넣어야 함.
UPDATE TB_DATA --SQL Server 2005
SET pk_new = b.ser
FROM TB_DATA a, (
    SELECT rank() OVER (PARTITION BY pk1, pk2 ORDER BY pk_old) as ser
    , pk1, pk2, pk_old
    FROM TB_DATA
) b
WHERE a.pk1 = b.pk1 and a.pk2 = b.pk2 and a.pk_old = b.pk_old

- 순번을 rank()를 사용하지 않고 구하는 방법도 있음.

- 위 구문에서 SET 절의 pk_new를 a.pk_new로 하면 다음과 같은 에러가 발생한다.
메시지 4104, 수준 16, 상태 1, 줄 2
여러 부분으로 구성된 식별자 "a.pk_new"은(는) 바인딩할 수 없습니다.


데이터베이스 문제점 파악 방법

어떤 계정으로
어느 시스템에서
어느 데이터베이스를 사용했을때
어떤 프로그램을 통해서
어떤 쿼리를 실행시켰을때
상황이 어떠하며
에러가 발생했는지를 확인하는 것이 중요하다.

SQL Server는 Profiler를 이용하는 것이 가장 좋다.

사례1) SQL Server 에서 락이 발생
app_user 로 로그인해서 : sp_who
dev_server 에서 쿼리를 실행함. : sp_who
ERP 데이터베이스를 사용 : sp_who
알 수 없는 쿼리 : dbcc inputbuffer(spid), 쿼리 확인
X Lock 을 걸고, 다른 프로세스에서 SELECT 를 하는데 락이 걸림 : sp_lock

[todo] 오라클에서는?

NULL 주의

- SQL Server 2000

- NULL과 연산을 하면 NULL이다.


- NULL을 찾을때는 IS를 사용해야 한다.(=이 아님)

CASE 구문내에 SELECT 사용하기

1. 데이터의 상태변경 이력을 기록해 두었다가 출력하는 기능이 필요했다.

2. 이력데이터를 가져와서 출력하는데 상태를 변경한 아이디는 있는데 이름이 없어서 ERP시스템에서 데이터를 가져와야 했다.

3. 사용자 아이디는 4가지로 구분된다.
관리자, 시스템, 본사직원, 업체직원
관리자 아이디는 admin
시스템은 실제 존재하지는 않는 아이디임(백그라운드 프로세스가 처리하는 경우) SYSTEM
본사직원 테이블은 TB_EMPLOYEE
업체직원 테이블은 TB_VENDOR

4. CASE 구문을 사용하고 각 조건 아래 SELECT 구문을 넣으면 될거 같다.
그런데 안된다.(나중에 알았는데 SELECT 컬럼명, 이렇게 해야 하는데 컬럼명을 안적었음)

- 1) 필요한 데이터를 테이블(z)로 구성한다.
- 2) 위와 동일한테 전체를 가져옴. 쿼리를 실행시키면 15초 정도 걸리는데 프로그램으로 실행하면 2초내에 출력된다. =-=>???
- 3) 안되는줄 알았는데 된다.
- 4) 함수로 만드는게 제일 좋을듯.

쿼리문에서 홑따옴표

입력하려는 데이터중에 홑따옴표가 있으면 에러난다.
홑따옴표를 하나 더 적어준다.


이거 예전에 많이 봤던거 아닌가?

일련번호중 비어 있는 값 찾아내기

시퀀스나 최대값으로 일련번호를 매기는 경우 중간에 값이 비는 경우가 있다.
중간에 비어 있는 값을 찾아내는 방법
- http://www.oracleclub.com/article/25103
=-=> ^= 는 ...?

행 만들기

COPY_T 를 이용해서 없는 행을 만들곤 했는데
이렇게도 됨.

유무를 판단하는 여러 방법

금액이 있으면 일수에 포함되고 금액이 없으면 일수에 포함하지 않는 경우

- http://oracleclub.com/article/25003
금액이 -인 경우도 고려해야 함. sign은 -1000이면 -1을 반환함.

==따지고 보면 sign이라는 함수는
case when amt > 0 then 1 
    when amt < 0 then -1
    else 0 end ==>이걸 구현한 거다. 이런 실생활에 도움이 되는 수학...



[비교] UPDATE


- MariaDB


임시 테이블

임시테이블 맞나?

소계, 합계 처리

소계, 합계를 나타내야 하는 화면이 있음.

- 데이터를 가져와서 뿌려 주고, 계산은 루프내에서 프로그램이 수행

- 쿼리에서 해결

좋은 코딩 습관 - 리턴값 확인

자바는 예외로 처리할 수 있지만 C 언어같은 경우는 실행성공유무를 리턴값으로 돌려 준다.
이런 리턴값을 확인하지 않고 넘어가는 경우 디버깅하기가 힘들다.

SQL 관련 처리를 할때도 INSERT/UPDATE/DELETE 구문을 실행한 후에 삽입/수정/삭제된 개수를 알수 있다.
이 개수를 확인하지 않아서 프로그램에 구멍이 생기는 경우가 많다.
적용된 개수를 반드시 확인하도록 한다.

변경 쿼리문 실행시 반드시 트랜잭션 걸 것! /////운영팁, 쿼리문에 변경할 데이터 조건에 거는거


업데이트 구문을 실행하기 전에 데이터를 확인하기 위해 위와 같이 쿼리를 사용하곤 한다.
그런데 실수로 SELECT 절의 주석을 없애고 실행시켰다.
그 결과 모든 데이터의 col1 이 test 로 되버렸다.
헉...

예전에 카드결제 데이터 몇 천건 말아먹은 적이 있는데[각주:1] 그 이후로 사소한 변경 쿼리문에서도 트랜잭션을 걸었다.
몇 년이 지나서 요즘 귀찮아서 트랜잭션을 안걸었는데 딱 걸렸다.
다행히 테스트 디비라 관계없지만 조심해야겠다.



  1. 뭔가 잘못되었다는 것을 알았을때 땀방울이 등을 타고 내렸다. [본문으로]

문자열 함수


=-=> oracle?