Oracle에서 PostgreSQL로 변환
SQL Developer의 Database Export나 SQLcl이 테이블과 Insert 문을 담아 쓴 .sql 파일을 놓으면, 같은 테이블, 키, 인덱스, 데이터를 담은 PostgreSQL 스크립트를 다운로드할 수 있어요. PostgreSQL이(가) 그대로 담을 수 없는 값과 옮기지 않는 객체는 모두 보고서에 나와요.
18개 행 변환, 수정 없음, 거부 없음
shop_2024_oracle.sql의 테이블Oracle 덤프 · SQL Developer(으)로 작성됨 · utf-8
customers8개 행
7개 열 id bigint not null name varchar(100) not null email varchar(150) not null country varchar(2) not null is_active smallint not null signed_up timestamp(0) created_at timestamp(0) not null orders10개 행
9개 열 id bigint not null customer_id bigint not null invoice bigint status varchar(10) not null total numeric(10,2) not null items integer not null ordered_at timestamp(0) not null shipped_at timestamp(0) note varchar(255)
-- Written by IntoSQL from a Oracle dump. Load it with: psql -v ON_ERROR_STOP=1 -f <file>
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET synchronous_commit = off;
SET maintenance_work_mem = '512MB';
CREATE SEQUENCE invoice_numbers INCREMENT BY 1 MINVALUE 1 START WITH 1020;
CREATE TABLE customers (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name varchar(100) NOT NULL,
email varchar(150) NOT NULL,
country varchar(2) DEFAULT 'US' NOT NULL,
is_active smallint DEFAULT 1 NOT NULL,
signed_up timestamp(0),
created_at timestamp(0) DEFAULT LOCALTIMESTAMP NOT NULL,
CONSTRAINT customers_check1 CHECK (is_active IN (0, 1))
);
CREATE TABLE orders (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
customer_id bigint NOT NULL,
invoice bigint DEFAULT (nextval('invoice_numbers')),
status varchar(10) DEFAULT 'pending' NOT NULL,
total numeric(10,2) NOT NULL,
items integer DEFAULT 1 NOT NULL,
ordered_at timestamp(0) NOT NULL,
shipped_at timestamp(0),
note varchar(255),
CONSTRAINT orders_check1 CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled'))
);
COPY customers (id, name, email, country, is_active, signed_up, created_at) FROM stdin;
1 Ana Martínez ana@example.com MX 1 2023-01-15 00:00:00 2023-01-15 10:24:00.000000
2 Zoë Müller zoe@example.de DE 1 2023-02-03 00:00:00 2023-02-03 08:11:42.000000
3 José Peña jose@example.es ES 0 2023-03-21 00:00:00 2023-03-21 19:05:17.000000
4 李雷 lilei@example.cn CN 1 2023-05-09 00:00:00 2023-05-09 02:40:00.000000
5 Noah O'Brien noah@example.ie IE 1 \N 2023-06-30 14:00:00.000000
6 Amélie Laurent amelie@example.fr FR 1 2024-01-02 00:00:00 2024-01-02 09:30:00.000000
7 Ravi Patel ravi@example.in IN 0 2024-02-29 00:00:00 2024-02-29 23:59:59.000000
8 Sofia Rossi 🌻 sofia@example.it IT 1 2024-04-12 00:00:00 2024-04-12 12:12:12.000000
\.
COPY orders (id, customer_id, invoice, status, total, items, ordered_at, shipped_at, note) FROM stdin;
1 1 1000 shipped 129.9 3 2024-03-01 10:00:00 2024-03-02 16:30:00 \N
2 2 1001 paid 54 1 2024-03-02 11:15:00 \N Gift wrap 🎁
3 1 1002 cancelled 12.5 1 2024-03-03 09:45:00 \N Customer changed their mind
4 4 1003 shipped 980 12 2024-03-05 02:10:00 2024-03-07 08:00:00 请小心轻放
5 5 1004 pending 45.75 2 2024-03-08 17:20:00 \N Leave at the door; ring twice
6 6 1005 shipped 310.4 5 2024-03-10 13:00:00 2024-03-11 09:00:00 Fragile: "glass"
7 8 1006 paid 76.2 2 2024-03-11 18:45:00 \N \N
8 2 1007 paid 19.99 1 2024-03-12 08:00:00 \N Paid at the counter
9 3 1008 shipped 64 2 2024-03-14 15:30:00 \N Shipping date never recorded
10 7 1009 paid 1499 1 2024-03-15 21:05:00 \N C:\\Users\\ravi\\invoice.pdf
\.
-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX customers_customers_pk ON customers (id);
CREATE UNIQUE INDEX customers_customers_email_uk ON customers (email);
CREATE UNIQUE INDEX orders_orders_pk ON orders (id);
CREATE INDEX orders_orders_status_date_ix ON orders (status, ordered_at);
ALTER TABLE customers ADD CONSTRAINT customers_customers_pk PRIMARY KEY USING INDEX customers_customers_pk;
ALTER TABLE customers ADD CONSTRAINT customers_customers_email_uk UNIQUE USING INDEX customers_customers_email_uk;
ALTER TABLE orders ADD CONSTRAINT orders_orders_pk PRIMARY KEY USING INDEX orders_orders_pk;
ALTER TABLE orders ADD CONSTRAINT orders_customer_fk FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
ALTER TABLE orders VALIDATE CONSTRAINT orders_customer_fk;
EXCEPTION WHEN foreign_key_violation THEN
RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'orders_customer_fk';
END $f$;
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1), 9223372036854775807)::bigint, false);
COMMENT ON TABLE customers IS 'People who bought at least once';
SELECT setval(pg_get_serial_sequence('orders', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM orders)::numeric, 0) + 1, 1), 9223372036854775807)::bigint, false);
수정 사항
수정할 부분이 없었어요.
파일은 이 컴퓨터에서 변환되고 업로드되지 않아요.
다른 샘플:
Oracle에서 PostgreSQL로 바뀌는 점
각 행은 변환기가 적용하는 규칙이며, 규칙이 데이터를 바꿀 때 보고서에 쓰는 줄이 함께 나와요.
BOOLEAN (23ai)
boolean
TRUE와 FALSE는 true와 false 그대로예요.
VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG
varchar(n)과 text
Oracle이 바이트로 셌든 문자로 셌든 길이는 문자 수로 세므로 모든 값이 들어가요.
NUMBER, NUMBER(p,s), FLOAT(b)
numeric(p,s) 또는 bigint
NUMBER는 모든 자릿수를 유지해요. 정밀도 없는 NUMBER의 값이 모두 18자리 이하의 정수면 64비트 정수가 되고, 음수 스케일은 그만큼의 자릿수를 소수점 앞에 담아요.
DATE, TIMESTAMP(p)
timestamp(p)
Oracle의 DATE는 초 단위까지 시각을 담으므로 날짜와 시각이 돼요. 미국식이나 독일식 세션에서 내보내면 날짜가 시각과 세기 없이 쓰여요(DD-MON-RR). 이를 유지하려면 ISO 세션(SYYYY-MM-DD HH24:MI:SS)에서 내보내세요.
TIMESTAMP(7) to TIMESTAMP(9)
초 단위 6자리, 7번째 자리는 잘림
PostgreSQL은 마이크로초까지 유지해요. 7번째 자리(100나노초)는 반올림하지 않고 잘라서, 어떤 값도 다음 초나 다음 날로 넘어가지 않아요.
보고서 줄: fraction_cut
TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE
timestamptz, 같은 시점
timestamptz는 시점을 유지해요. PostgreSQL은 각 값의 오프셋 대신 세션 시간대로 표시해요.
JSON (21c), and CLOB holding JSON
jsonb
같은 JSON 값이에요. 내보내기가 'null'로 쓴 SQL NULL은 NULL 그대로예요.
BLOB, RAW(n), LONG RAW
bytea
바이트는 바이트 그대로 남아요.
ROWID, UROWID, XMLTYPE, SDO_GEOMETRY
text, XMLTYPE은 xml
Oracle 고유 타입에는 같은 타입이 없어요. 값은 텍스트를 유지하고 ROWID 값도 포함되지만, Oracle 밖에서는 의미가 없어요.
보고서 줄: type_replaced
collations that ignore case (BINARY_CI)
정확한 비교
PostgreSQL은 텍스트를 정확히 비교하므로, Oracle에서 대소문자를 무시하던 열도 이제 Ana와 ana를 구분해요.
보고서 줄: case_insensitive_collation
identity columns, and a sequence a BEFORE INSERT trigger assigns
GENERATED BY DEFAULT AS IDENTITY, 가장 큰 id 다음부터 이어짐
복사한 id는 그대로 불러오고, 카운터는 가장 큰 id 다음부터 이어져요. 트리거가 시퀀스로 값을 채우는 열(12c 이전 방식)도 identity 열이 돼요.
CREATE SEQUENCE
같은 옵션의 CREATE SEQUENCE
내보내기는 시퀀스가 도달한 위치를 START WITH로 쓰므로, 시퀀스는 거기서부터 이어져요.
virtual columns (GENERATED ALWAYS AS ... VIRTUAL)
생성 열, STORED
PostgreSQL 13부터 17까지는 생성 열을 저장 방식으로만 지원해요. 수식은 같고, Oracle처럼 NULL을 빈 값으로 보도록 ||를 써요.
보고서 줄: virtual_as_stored
virtual columns with functions IntoSQL doesn't write, and the || operator
일반 열
PostgreSQL용으로 쓸 수 없는 수식은 일반 열로 남고 보고서에 한 줄 기록돼요. 내보내기가 가상 열에 쓴 값은 제외되고, PostgreSQL이 계산할 값도 없어요.
보고서 줄: generated_not_translated
defaults with functions IntoSQL doesn't write (SYS_GUID(), ||)
기본값 없음
PostgreSQL용으로 쓸 수 없는 기본값은 제외하고 보고해요.
보고서 줄: default_not_translated
CHECK constraints
변환됨
같은 체크 제약이고, 각 행을 불러올 때 검사해요.
CHECK constraints with functions IntoSQL doesn't write
만들지 않음
PostgreSQL용으로 쓸 수 없는 체크 제약은 제외하고 보고해요.
보고서 줄: check_skipped
CHECK constraints that are DISABLE or ENABLE NOVALIDATE
만들지 않음
Oracle은 이미 있는 행에 이 체크 제약을 적용하지 않으므로 행이 이를 위반할 수 있어요.
보고서 줄: check_not_enforced
function-based, bitmap and domain indexes
만들지 않음
IntoSQL은 열에 대한 b-tree 인덱스를 써요. 다른 인덱스는 불러온 뒤 다시 만드세요.
보고서 줄: index_skipped
foreign keys
외래 키, 행 다음에
행은 순서와 상관없이 불러오고, 키가 그 뒤에 검사해요.
foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones
만들지 않음
키는 없는 테이블을 가리킬 수 없고, Oracle이 검사하지 않는 키에는 부모 행이 없는 행이 있을 수 있어요.
보고서 줄: foreign_key_skipped
partitioned tables
모든 파티션의 행을 담은 하나의 테이블
행은 같아요. 필요하면 PostgreSQL에서 테이블을 다시 파티션으로 나누세요.
보고서 줄: partitions_dropped
NOT NULL columns with values that become NULL
NOT NULL 제거
값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요.
보고서 줄: not_null_relaxed
views, synonyms, types, packages, procedures, functions and other triggers
보고서에 나열
코드가 PL/SQL로 작성되어 있어서 직접 다시 만들 수 있도록 나열해요.
보고서 줄: not_converted_objects
exports without CREATE TABLE (data only)
값으로 판단한 타입
데이터만 있는 내보내기에는 행만 있어서 타입을 값으로 판단해요.
보고서 줄: no_schema
expressions in INSERT values other than the ones exports write
NULL
데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요. 내보내기가 쓰는 to_date, to_timestamp, TO_CLOB, HEXTORAW 등은 읽어요.
보고서 줄: expression_value
types IntoSQL doesn't know, and object types
text
텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요.
보고서 줄: unknown_type
dates before year 1 and time zones given as region names
NULL
날짜가 아닌 값은 NULL이 되고 보고서에 개수가 나와요.
보고서 줄: date_out_of_range
NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE
NaN과 Infinity 유지
PostgreSQL의 부동소수점 타입은 NaN과 infinity를 담아요.
NUL characters in text
제거
PostgreSQL text는 NUL 문자를 담을 수 없어요. NUL 문자는 제거되고 보고서에 해당 값의 개수가 나와요.
보고서 줄: nul_removed
text that isn't valid in its encoding
잘못된 바이트를 대체 문자로
PostgreSQL 텍스트는 올바른 UTF-8이어야 해요.
보고서 줄: invalid_utf8_replaced
text decoded twice (ñ)
그대로 복사
스크립트에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요.
보고서 줄: mojibake_suspected
| Oracle에서 | PostgreSQL에서 | 보고서 줄 |
|---|---|---|
| BOOLEAN (23ai) | booleanTRUE와 FALSE는 true와 false 그대로예요. | |
| VARCHAR2(n BYTE|CHAR), NVARCHAR2(n), CHAR(n), NCHAR(n), CLOB, NCLOB, LONG | varchar(n)과 textOracle이 바이트로 셌든 문자로 셌든 길이는 문자 수로 세므로 모든 값이 들어가요. | |
| NUMBER, NUMBER(p,s), FLOAT(b) | numeric(p,s) 또는 bigintNUMBER는 모든 자릿수를 유지해요. 정밀도 없는 NUMBER의 값이 모두 18자리 이하의 정수면 64비트 정수가 되고, 음수 스케일은 그만큼의 자릿수를 소수점 앞에 담아요. | |
| DATE, TIMESTAMP(p) | timestamp(p)Oracle의 DATE는 초 단위까지 시각을 담으므로 날짜와 시각이 돼요. 미국식이나 독일식 세션에서 내보내면 날짜가 시각과 세기 없이 쓰여요(DD-MON-RR). 이를 유지하려면 ISO 세션(SYYYY-MM-DD HH24:MI:SS)에서 내보내세요. | |
| TIMESTAMP(7) to TIMESTAMP(9) | 초 단위 6자리, 7번째 자리는 잘림PostgreSQL은 마이크로초까지 유지해요. 7번째 자리(100나노초)는 반올림하지 않고 잘라서, 어떤 값도 다음 초나 다음 날로 넘어가지 않아요. | fraction_cut |
| TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE | timestamptz, 같은 시점timestamptz는 시점을 유지해요. PostgreSQL은 각 값의 오프셋 대신 세션 시간대로 표시해요. | |
| JSON (21c), and CLOB holding JSON | jsonb같은 JSON 값이에요. 내보내기가 'null'로 쓴 SQL NULL은 NULL 그대로예요. | |
| BLOB, RAW(n), LONG RAW | bytea바이트는 바이트 그대로 남아요. | |
| ROWID, UROWID, XMLTYPE, SDO_GEOMETRY | text, XMLTYPE은 xmlOracle 고유 타입에는 같은 타입이 없어요. 값은 텍스트를 유지하고 ROWID 값도 포함되지만, Oracle 밖에서는 의미가 없어요. | type_replaced |
| collations that ignore case (BINARY_CI) | 정확한 비교PostgreSQL은 텍스트를 정확히 비교하므로, Oracle에서 대소문자를 무시하던 열도 이제 Ana와 ana를 구분해요. | case_insensitive_collation |
| identity columns, and a sequence a BEFORE INSERT trigger assigns | GENERATED BY DEFAULT AS IDENTITY, 가장 큰 id 다음부터 이어짐복사한 id는 그대로 불러오고, 카운터는 가장 큰 id 다음부터 이어져요. 트리거가 시퀀스로 값을 채우는 열(12c 이전 방식)도 identity 열이 돼요. | |
| CREATE SEQUENCE | 같은 옵션의 CREATE SEQUENCE내보내기는 시퀀스가 도달한 위치를 START WITH로 쓰므로, 시퀀스는 거기서부터 이어져요. | |
| virtual columns (GENERATED ALWAYS AS ... VIRTUAL) | 생성 열, STOREDPostgreSQL 13부터 17까지는 생성 열을 저장 방식으로만 지원해요. 수식은 같고, Oracle처럼 NULL을 빈 값으로 보도록 ||를 써요. | virtual_as_stored |
| virtual columns with functions IntoSQL doesn't write, and the || operator | 일반 열PostgreSQL용으로 쓸 수 없는 수식은 일반 열로 남고 보고서에 한 줄 기록돼요. 내보내기가 가상 열에 쓴 값은 제외되고, PostgreSQL이 계산할 값도 없어요. | generated_not_translated |
| defaults with functions IntoSQL doesn't write (SYS_GUID(), ||) | 기본값 없음PostgreSQL용으로 쓸 수 없는 기본값은 제외하고 보고해요. | default_not_translated |
| CHECK constraints | 변환됨같은 체크 제약이고, 각 행을 불러올 때 검사해요. | |
| CHECK constraints with functions IntoSQL doesn't write | 만들지 않음PostgreSQL용으로 쓸 수 없는 체크 제약은 제외하고 보고해요. | check_skipped |
| CHECK constraints that are DISABLE or ENABLE NOVALIDATE | 만들지 않음Oracle은 이미 있는 행에 이 체크 제약을 적용하지 않으므로 행이 이를 위반할 수 있어요. | check_not_enforced |
| function-based, bitmap and domain indexes | 만들지 않음IntoSQL은 열에 대한 b-tree 인덱스를 써요. 다른 인덱스는 불러온 뒤 다시 만드세요. | index_skipped |
| foreign keys | 외래 키, 행 다음에행은 순서와 상관없이 불러오고, 키가 그 뒤에 검사해요. | |
| foreign keys to tables the export doesn't create, and DISABLE or NOVALIDATE ones | 만들지 않음키는 없는 테이블을 가리킬 수 없고, Oracle이 검사하지 않는 키에는 부모 행이 없는 행이 있을 수 있어요. | foreign_key_skipped |
| partitioned tables | 모든 파티션의 행을 담은 하나의 테이블행은 같아요. 필요하면 PostgreSQL에서 테이블을 다시 파티션으로 나누세요. | partitions_dropped |
| NOT NULL columns with values that become NULL | NOT NULL 제거값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요. | not_null_relaxed |
| views, synonyms, types, packages, procedures, functions and other triggers | 보고서에 나열코드가 PL/SQL로 작성되어 있어서 직접 다시 만들 수 있도록 나열해요. | not_converted_objects |
| exports without CREATE TABLE (data only) | 값으로 판단한 타입데이터만 있는 내보내기에는 행만 있어서 타입을 값으로 판단해요. | no_schema |
| expressions in INSERT values other than the ones exports write | NULL데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요. 내보내기가 쓰는 to_date, to_timestamp, TO_CLOB, HEXTORAW 등은 읽어요. | expression_value |
| types IntoSQL doesn't know, and object types | text텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요. | unknown_type |
| dates before year 1 and time zones given as region names | NULL날짜가 아닌 값은 NULL이 되고 보고서에 개수가 나와요. | date_out_of_range |
| NaN and Infinity in BINARY_FLOAT and BINARY_DOUBLE | NaN과 Infinity 유지PostgreSQL의 부동소수점 타입은 NaN과 infinity를 담아요. | |
| NUL characters in text | 제거PostgreSQL text는 NUL 문자를 담을 수 없어요. NUL 문자는 제거되고 보고서에 해당 값의 개수가 나와요. | nul_removed |
| text that isn't valid in its encoding | 잘못된 바이트를 대체 문자로PostgreSQL 텍스트는 올바른 UTF-8이어야 해요. | invalid_utf8_replaced |
| text decoded twice (ñ) | 그대로 복사스크립트에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요. | mojibake_suspected |
스크립트를 PostgreSQL에 불러오기
스크립트는 테이블을 만들고 행을 복사한 다음 키, 인덱스, 외래 키를 추가해요. 그래서 빨리 불러오고 첫 오류에서 멈춰요.
psql -v ON_ERROR_STOP=1 -d mydb -f oracle.postgresql.sql외래 키는 NOT VALID로 추가한 다음 검증해요. 어떤 행이 존재하지 않는 행을 가리키면, 중간에 실패하지 않고 어떤 제약인지 알려 줘요.
큰 덤프는 데이터베이스를 먼저 만들고, 서버와 같은 컴퓨터에서 psql로 스크립트를 실행하세요.
IntoSQL Pro는 데스크톱 앱이나 명령줄에서 파일을 PostgreSQL에 바로 불러와요. 스크립트를 따로 만들 필요가 없어요.
좋은 결과를 위한 Oracle 덤프 방법
변환기는 덤프에 담긴 내용을 읽어요. 다음 옵션을 쓰면 더 많은 데이터가 덤프에 남아요:
- SQL Developer에서 Tools, Database Export를 고르고 DDL과 Insert 데이터 형식을 선택하세요. SQLcl은 SET SQLFORMAT INSERT로 같은 결과를 써요.
- 내보내기 전에 ALTER SESSION SET NLS_DATE_FORMAT = 'SYYYY-MM-DD HH24:MI:SS'를 실행하세요. 기본 형식은 날짜를 시각과 세기 없이 써요.
- exp나 expdp의 .dmp 파일은 바이너리예요. Oracle 데이터베이스(예: Docker의 Oracle Database Free)로 가져온 뒤 SQL Developer로 내보내세요.
변환되지 않는 것
뷰, 패키지, 프로시저, 함수, 트리거, 타입, 동의어는 PL/SQL로 작성돼요. 보고서에 이름으로 나열되고 몰래 빠지는 일은 없으므로, PostgreSQL에 맞게 다시 작성할 수 있어요.
Oracle에서 PostgreSQL로 변환에 관한 질문
여기에 답이 없나요? 문의 페이지로 연락하시면 담당자가 답장해요. 문의 페이지
덤프가 업로드되나요?
아니요. 변환기는 브라우저에서 실행되고 디스크의 덤프를 조각조각 읽으므로, 덤프가 컴퓨터 밖으로 나가지 않아요. 데스크톱 앱과 명령줄도 컴퓨터에서 변환해요.
덤프는 얼마나 커도 되나요?
변환기는 덤프 전체를 메모리에 올리지 않아요. 파일을 범위별로 두 번 읽고, 읽는 대로 스크립트를 써요. 수 GB 덤프도 브라우저, 데스크톱 앱, 명령줄에서 변환돼요.
exp나 expdp의 .dmp 파일을 변환할 수 있나요?
직접은 안 돼요. Data Pump와 기존 Export는 Oracle만 읽을 수 있는 바이너리 형식으로 써요. 아무 Oracle 데이터베이스(Oracle Database Free는 Docker에서 실행돼요)로 가져온 뒤 SQL Developer의 Database Export나 SQLcl로 내보내세요. 변환기는 .dmp 파일을 받으면 이를 알려 줘요.
어떤 Oracle 버전의 내보내기를 읽나요?
Oracle 11g 이상에서 SQL Developer와 SQLcl로 만든, DBMS_METADATA의 테이블 정의를 담은 내보내기예요. 모든 테스트 내보내기는 Oracle 21c와 23ai에서 미국식, 독일식, ISO 세션으로 만들고 원본과 셀 단위로 비교해요.
NUMBER, DATE 등 Oracle 타입은 어떻게 되나요?
NUMBER는 numeric이 되고, 모든 값이 정수면 bigint가 돼요. DATE는 시각을 유지한 채 timestamp가 되고, CLOB은 text, BLOB과 RAW는 bytea, BINARY_DOUBLE은 NaN과 Infinity를 포함한 double precision, interval은 interval이 돼요.
identity 열과 시퀀스는 유지되나요?
네. identity 열은 identity 열로 남아 가장 큰 id 다음부터 이어지고, 트리거가 시퀀스로 채우는 열도 마찬가지예요. 시퀀스는 내보내기에 적힌 위치부터 이어져요.
PL/SQL 패키지, 프로시저, 트리거는 어떻게 되나요?
데이터베이스마다 자체 언어로 작성하므로 변환하지 않고 보고서에 이름으로 나열해요.
스크립트는 어떤 PostgreSQL 버전에서 불러올 수 있나요?
PostgreSQL 13부터 18까지예요. 모든 버전에서 같은 스크립트를 불러올 수 있고, 문제가 생기면 첫 오류에서 멈춰요.