간단한 TIP정도라고 할 수 있는 포스팅입니다.
테이블에 레코드를 삽입(INSERT) 할 때, 종종 레코드 컬럼으로 일련번호 또는 순번이 있는 경우, 해당 테이블에 저장되어 있는 모든 레코드의 해당 컬럼 중에서 가장 큰 값을 가지고 있는 해당 컬럼 값을 찾아 1을 더해 삽입해주고 싶은 경우가 필요할 때가 있습니다.
다음과 같은 테이블이 있을 때, display_order는 사용자 화면에 표시되는 순서라고 하고, 어떤 데이터가 삽입되던 간에 현재 저장되어 있는 값보다 1 더 큰 수를 삽입하고 싶습니다.
[테이블 : TBL_FRUITS]
data_code |
data_name |
display_order |
1001 |
사과 |
1 |
1002 |
파인애플 |
2 |
1003 |
수박 |
3 |
1004 |
복숭아 |
4 |
다음과 같이 코드를 작성해 보았습니다.
INSERT INTO TBL_FRUITS (data_code , data_name, display_order)
VALUES('1005', '포도', MAX(display_order))
제대로 작성한 것 같습니다. 하지만 실행하면 쿼리 오류가 발생합니다.
이름 "display_order"은(는) 이 컨텍스트에서 사용할 수 없습니다. 올바른 식은 상수, 상수 식 및 변수(일부 컨텍스트의 경우)입니다. 열 이름은 사용할 수 없습니다.
INSERT 할 때, VALUES 내의 인자로 올 수 있는 것은, 상수, 상수 식 및 변수 형태이어야 합니다. 열 이름은 사용할 수 없다고 합니다. display_order는 열 이름입니다.
그럼 조금 수정해서 다음과 같이 코드를 작성해 보았습니다.
INSERT INTO TBL_FRUITS (data_code , data_name, display_order)
VALUES('1005', '포도', (SELECT MAX(display_order) FROM TBL_FRUITS))
이번에는 열 이름이 아니라, 서브 쿼리 형태로 작성해 보았는데, 역시나 오류가 발생합니다.
이 컨텍스트에는 하위 쿼리를 사용할 수 없습니다. 스칼라 식만 사용할 수 있습니다.
VALUES 인자로 스칼라 형태의 결과 값만 올 수 있습니다. (위의 쿼리는 테이블 형태의 결과를 줍니다.)
다음과 같이 작성하면 원하는 결과를 얻을 수 있습니다.
1번 쿼리)
INSERT INTO TBL_FRUITS
SELECT '1005', '포도', ISNULL(MAX(display_order) + 1, 1) FROM TBL_FRUITS
2번 쿼리)
INSERT INTO TBL_FRUITS
SELECT '1005', '포도', ISNULL((SELECT MAX(display_order) + 1 FROM TBL_FRUITS), 1)
INSERT + VALUES 조합을 사용하지 않고, INSERT + SELECT 를 사용했습니다.
SELECT 를 통해서 나온 결과 레코드를 바로 INSERT 하는 방식입니다.
SELECT 구문에서는 당연히 열 이름을 사용할 수 있으며, 서브 쿼리도 사용할 수 있습니다.
1번과 2번 쿼리는 미묘하게 차이는 있지만, 모두 정상적으로 실행되는 쿼리이며,
1번 쿼리는 SELECT 쿼리에 열 이름을 사용한 방식이고,
2번 쿼리는 SELECT 쿼리에 서브(하위) SELECT 쿼리를 사용한 방식입니다.
참고로 위와 같은 쿼리 구문이 올바르게 동작하도록 하기 위해서는 반드시 SELECT 를 통해서 나온 레코드의 컬럼 수와 타입이 INSERT 하려는 테이블의 컬럼의 그것들과 동일해야 합니다.
'개발&컴퓨터 > DB' 카테고리의 다른 글
[오라클] ORA-30926: 원본 테이블의 고정 행 집합을 가져올 수 없습니다 (0) | 2014.11.23 |
---|---|
[MSSQL] SQL Server 에이전트 이용하여 DB 자동 백업 설정하기 (0) | 2014.11.05 |
[MSSQL] 백업 세트에 기존 데이터베이스가 아닌 데이터베이스의 백업이 있습니다 (오류해결방법) (6) | 2014.10.04 |
MSSQL 예상 실행 계획으로 프로시져(또는 쿼리) 개선하기. (1) | 2014.09.19 |
[오라클] 문자열 자르기. (0) | 2014.09.03 |