같은 기능이라도 DB마다 함수 이름과 인자 순서가 다릅니다. 아래 표는 "같은 일"을 기준으로 각 DB 의 함수 이름과, H2 에서 실제로 실행되는 대안을 정리한 것입니다.
| 기능 | Oracle·Tibero | MySQL | MSSQL | H2 실행 대안 |
|---|---|---|---|---|
| 자르기 | SUBSTR |
SUBSTRING(SUBSTR 도 됨) |
SUBSTRING |
SUBSTR 공통 |
| 찾기(위치) | INSTR |
LOCATE·INSTR |
CHARINDEX |
INSTR 공통 |
| 길이(문자 수) | LENGTH |
CHAR_LENGTH |
LEN |
CHAR_LENGTH 공통 |
| 길이(바이트 수) | LENGTHB(H2 미지원) |
LENGTH(바이트 수) |
DATALENGTH(H2 미지원) |
OCTET_LENGTH |
| 채우기 | LPAD·RPAD |
LPAD·RPAD |
없음(4절 변형7) | LPAD·RPAD |
| 공백 제거 | TRIM |
TRIM |
TRIM |
TRIM 공통 |
| 치환 | REPLACE |
REPLACE |
REPLACE |
REPLACE 공통 |
| 첫 글자만 대문자 | INITCAP(H2 미지원) |
없음 | 없음 | 4절 변형5 |
| 문자열 연결 | || |
CONCAT |
+ |
||·CONCAT 공통 |
핵심이 표에서 마지막 열(H2 실행 대안)이 가장 중요합니다.
INSTR·CHAR_LENGTH·TRIM·REPLACE처럼 표준에 가까운 함수는 DB를 가리지 않고 그대로 쓰면 되고, DB마다 이름이 완전히 다른 함수만 3절·4절에서 방언별로 비교합니다.
날짜 함수는 문자 함수보다 차이가 더 큽니다. 개월 더하기·월말 구하기 같은 기본 동작조차 함수 이름이 DB마다 다르고, H2 가 지원하지 않는 함수도 많습니다.
| 기능 | Oracle·Tibero | MySQL | MSSQL | H2 실행 대안 |
|---|---|---|---|---|
| 개월 더하기 | ADD_MONTHS |
DATE_ADD(H2 미지원) |
DATEADD |
DATEADD·INTERVAL |
| 월말 구하기 | LAST_DAY |
LAST_DAY |
EOMONTH(H2 미지원, 2012+) |
LAST_DAY |
| 월초 구하기 | TRUNC(d,'MM')(H2 미지원) |
전용 함수 없음 | 전용 함수 없음 | DATE_TRUNC |
| 날짜 차이(일) | 날짜끼리 빼기 | DATEDIFF(a,b)(H2 는 3인자만) |
DATEDIFF(단위,a,b) |
DATEDIFF('DAY',a,b) |
| 날짜 차이(개월) | MONTHS_BETWEEN(H2 미지원) |
전용 함수 없음 | 전용 함수 없음 | DATEDIFF('MONTH',a,b) |
| 날짜→문자 | TO_CHAR |
DATE_FORMAT(H2 미지원) |
CONVERT 스타일(H2 미지원) |
FORMATDATETIME |
| 문자→날짜 | TO_DATE |
STR_TO_DATE(H2 미지원) |
CONVERT·CAST |
PARSEDATETIME |
DATE_TRUNC·DATEDIFF('DAY', ...)·FORMATDATETIME·PARSEDATETIME 은 H2 자체 함수로, 실제 Oracle·MySQL·MSSQL 에는 없는 이름입니다. H2 로 결과를 확인하는 용도로만 쓰고 실제 DB 코드에는 그 DB 의 함수 이름을 그대로 씁니다.
LENGTH·CHAR_LENGTH 는 문자 개수를 세고, LENGTHB·DATALENGTH 는 바이트 개수를 셉니다. 영문·숫자는 1자가 1바이트지만, UTF-8 로 인코딩한 한글은 1자가 3바이트라 두 값이 크게 벌어집니다.
3절의 예제 1·3 에서 확인하듯 '김민준' 은 문자 수 3, 바이트 수 9 입니다. 화면에 보여줄 글자 수를 셀 때는 문자 수 함수를, DB 컬럼의 바이트 한도(예: VARCHAR2(20))를 계산할 때는 바이트 수 함수를 써야 합니다.
주의실제 MySQL 의
LENGTH는 바이트 수를 반환하지만, H2 의 MySQL 모드는LENGTH를CHAR_LENGTH와 똑같이 문자 수로 계산합니다(H2 에서 재현 안 됨, 문법 검토만). 실제 MySQL 코드를 작성할 때는 문자 수가 필요하면CHAR_LENGTH, 바이트 수가 필요하면LENGTH를 써야 합니다.
Oracle 의 DATE 타입은 겉보기에 날짜만 있어 보여도 시·분·초까지 항상 가지고 있습니다. BETWEEN 시작일 AND 종료일 로 범위를 걸면, 종료일이 자정(00:00:00)으로 해석되어 종료일 당일에 생긴 데이터를 놓치기 쉽습니다.
4절 변형4 에서 ord_ts(시간 포함)를 BETWEEN DATE '2024-02-01' AND DATE '2024-02-15' 로 조회하면 2월 15일 낮에 생긴 주문이 빠집니다. 안전한 패턴은 >= 시작일 AND < 다음날 로, 종료 경계를 다음 날 자정 미만으로 잡아 시간 성분과 무관하게 해당 날짜 전체를 포함합니다.
주의
BETWEEN은 두 경계를 모두 포함하지만, 종료일에 시간을 적지 않으면 그날 0시 정각만 포함되고 나머지 시간은 빠집니다. 날짜 컬럼에 시간이 섞일 가능성이 있다면BETWEEN대신>= 시작 AND < 다음날패턴을 씁니다.