안녕하세요. 쿼리를 안짜보다 짜니.. 정말 못짜는걸 느끼게 되는데요..ㅠㅠ
데이터 이관을 좀 쉽게 하기 위해 쿼리 작성 중 질문 하나 드립니다.
우선 구현하고 싶은 로직은 USER_TAB_COLUMNS의 전체 테이블 컬럼이름과, 데이터타입을 새로운 테이블 TARGET_ETL에 조건들과 비교해서 to-be datatype들을 도출해 내고 싶은데요.
target_etl 테이블 내용(조건)은 캡처에 추가해두었습니다.
현재 제가 지금까지 쫘논 쿼리는 아래와 같은데, 조건을 어떻게 줘야할지 고민됩니다.
아래는 예시입니다.
데이터타입이 user_tab_columns테이블의 타입과 동일하고, 길이도 같으면 varchar2는 text형태로, (ex varchar2,4000 -text)
데이터타입만 동일한 경우 (varchar2-> varchar) 이런식으로 조건을 주고 싶습니다. 현재는 varchar2, 4000일 경우에 두가지 조건에 다 만족해서 varchar, text 두건씩 중복되어 나옵니다.
이 로직을 어떻게 구현해야 할지 고민중인데, 의견좀 부탁드립니다.
말주변이 없어 이해 하실런지 잘 모르겠습니다..샘플 결과도 올려두었습니다.
일단지금까지 짠 쿼리는 아래와 같은데,,
case 조건을 어떻게 해야될지 모르겠네요.
한번 봐주세요
SELECT CASE WHEN RM = '1' THEN 'CREATE TABLE '||TABLE_NAME ||'( '||COLUMN_NAME||' '||TARGET||'('||TARGET_LENGTH || '),' ELSE '' END TABLE_NAME,
COLUMN_NAME,
DATA_TYPE ASIS,
DATA_LENGTH,
TARGET TOBE,
TARGET_LENGTH
FROM (SELECT TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
DATA_LENGTH,
TARGET,
TARGET_LENGTH,
ROW_NUMBER () OVER (PARTITION BY TABLE_NAME ORDER BY TABLE_NAME) RM
FROM (SELECT A.TABLE_NAME,
A.COLUMN_NAME,
A.DATA_TYPE,
A.DATA_LENGTH,
CASE
WHEN A.DATA_TYPE = B.DATA_TYPE AND A.DATA_LENGTH = B.DATA_LENGTH THEN B.TARGET_TYPE
WHEN A.DATA_TYPE = B.DATA_TYPE THEN B.TARGET_TYPE
END TARGET,
B.TARGET_LENGTH
FROM USER_TAB_COLUMNS A, TARGET_ETL B
WHERE A.DATA_TYPE = B.DATA_TYPE))
CASE
WHEN A.DATA_TYPE = B.DATA_TYPE AND A.DATA_LENGTH = B.DATA_LENGTH THEN B.TARGET_TYPE
WHEN A.DATA_TYPE = B.DATA_TYPE THEN B.TARGET_TYPE
이 조건절에 어떻게 줘야할지 고민이네요..
예를들어서 varchar2 4000 이면 text가 나와야하고, varchar2면 varchar가 나와야 하는데, 현재는 둘다 나오네요..
아래와 같이요.
SESSION_ID VARCHAR2 500 VARCHAR
SESSION_ID VARCHAR2 500 TEXT
꼭 그리 해야한다면
SELECT *
FROM (
SELECT a.table_name
, a.column_name
, a.data_type
, b.target_type
, a.data_length
, ROW_NUMBER () OVER ( PARTITION BY a.table_name, a.column_name, a.data_type ORDER BY CASE WHEN a.data_type = b.data_type AND a.data_length = b.data_length THEN 1 ELSE 2 END ASC, b.target_type DESC ) rn
FROM USER_TAB_COLUMNS a
, t b
WHERE a.data_type = b.data_type
)
WHERE rn = 1
어후..쿼리 짱이네요.. 저런방법도 있네요..
전 무지하게 아래같이 짜고 있었습니다..^^ 감사합니다.
SELECT TABLE_NAME
, COLUMN_NAME
, DATA_TYPE
, DATA_LENGTH
, CASE
-- 문자형
WHEN DATA_TYPE = 'VARCHAR2' AND DATA_LENGTH = '200' AND SUBSTR(TABLE_NAME,1,2) ='IF' THEN 'VARCHAR(255)'
WHEN DATA_TYPE = 'VARCHAR2' AND DATA_LENGTH > '256' THEN 'TEXT'
WHEN DATA_TYPE = 'VARCHAR2' AND DATA_LENGTH < '254' THEN 'VARCHAR('||DATA_LENGTH||')'
-- 날짜형
WHEN DATA_TYPE = 'DATE' THEN 'TIMESTAMP'
-- 숫자형
WHEN DATA_TYPE = 'NUMBER' AND SUBSTR(COLUMN_NAME,-3) = 'SEQ' THEN 'INT(11)'
WHEN DATA_TYPE = 'NUMBER' AND SUBSTR(COLUMN_NAME,-4) = 'RATE' OR SUBSTR(COLUMN_NAME,-5) = 'RATIO' THEN 'FLOAT'
END TARGET
FROM USER_TAB_COLUMNS