728x90
학습목표
- VMware에 Rocky Linux 8.10 설치
- Oracle 19c 설치
- 데이터베이스 실행 및 사용자, 테이블 생성, 데이터 생성
- 테이블 생성, 데이터 생성(PL/SQL) SQL Script
1. VMware에 Rocky Linux 8.10 설치 Rocky Linux 설치
- Rocky Linux : Rocky Linux는 RHEL(Red Hat Enterprise Linux)과 100% 호환되는 무료 오픈소스 리눅스 배포판, CentOS의 대체재로 탄생
- https://dl.rockylinux.org/pub/rocky/8/isos/x86_64/ 들어가서 iso 다운로드
- ISO 파일은 CD나 DVD의 이미지 파일로, 국제 표준화 기구(ISO)가 제정한 광학 디스크의 압축 파일. "이미지 파일”이라고도 불림. 마치 디스크를 사진처럼 찍어서 파일로 만든 느낌

- VMware 세팅

네트워크 유형 | 설명 | 외부 네트워크 연결 가능 여부 |
Bridged (VMnet0) | 게스트 OS가 실제 물리 네트워크와 직접 연결됨 (공유기에서 IP 할당) | ✅ 가능 |
NAT (VMnet8) | VMware가 가상 게이트웨이 역할을 하며, 게스트 OS가 NAT을 통해 인터넷 연결 가능 | ✅ 가능 |
Host-Only (VMnet1) | 게스트 OS와 호스트 OS 간에만 통신 가능, 외부 네트워크 연결 불가 | ❌ 불가능 |
Custom | 사용자가 직접 네트워크 환경을 설정 가능 | 설정에 따라 다름 |
2. Oracle 19c 설치
- oracle 19c rpm 다운로드(yum 안돼서 직접 ISO 파일 다운 or SSH로 로컬 PC에서 VMware로 파일전송)

- oracle-database-preinstall-19c 설치
sudo dnf install -y oracle-database-preinstall-19c
# sudo : superuser do (관리자 권한으로 실행)
# dnf : Dandified YUM, RPM 기반 리눅스 배포판을 위한 패키지 관리도구
# install -y dnf가 설치를 시작하기 전에 물어보면 -y를 넣으면 자동으로 yes
- Oracle 19c가 동작하는 데 필요한 라이브러리 및 유틸리티 패키지들을 자동으로 설치(glibc, binutils, gcc, libaio, make 등)
- Oracle이 원활하게 실행되도록 공유 메모리, 파일 핸들 수, 네트워크 설정 등을 자동으로 변경(설정 파일: /etc/sysctl.conf)
- kernel.shmmax = 4398046511104 # 공유 메모리 최대 크기
- kernel.shmall = 1073741824 # 공유 메모리 페이지 수
- fs.file-max = 6815744 # 최대 파일 핸들 개수

- 오라클 설치 전
mkdir -p /u01/app/oracle # 오라클 데이터베이스가 설치될 기본 디렉토리
chown -R oracle:oinstall /u01/app/oracle # 소유자를 oracle로 변경
chmod -R 775 /u01/app/oracle # 적절한 권한을 부여
- 오라클 사용자로 전환 후 설치 작업 ( su - oracle )
- 사용자 프로파일 수정 vi /home/oracle/.bash_profile

- ORACLE_BASE : 오라클 기본 디렉토리
- ORACLE_HOME : 오라클 프로그램이 설치된 디렉토리
- ORACLE_SID : 데이터베이스 인스턴스 이름
- PATH : 오라클 실행 파일을 PATH에 추가
- NLS_LANG : 오라클 메시지 시스템 설정이 한국어라 깨짐 방지로 설정 필요
- 이후 바뀐 설정 적용 명령어 : source /home/oracle/.bash_profile
- which dbca 명령어로 dbca 확인 후 실행
- dbca (Database Configuration Assistant) : 데이터베이스를 자동으로 생성하는 유틸리티
dbca -silent -createDatabase \
-gdbName orcl \
-sid orcl \
-templateName "General_Purpose.dbc" \
-characterSet AL32UTF8 \
-memoryPercentage 40 \
-emConfiguration NONE \
-sysPassword ora951753 \
-systemPassword ora951753 \
-createAsContainerDatabase true
옵션 | 설명 |
-silent | 무인 설치 (GUI 없이 자동 실행) |
-createDatabase | 새 데이터베이스 생성 |
-gdbName orcl | 전역 데이터베이스 이름 설정 |
-sid orcl | 인스턴스 이름 (SID) 설정 |
-templateName "General_Purpose.dbc" | 템플릿 지정 (OLTP용) |
-characterSet AL32UTF8 | 문자셋 UTF-8 설정 (다국어 지원) |
-memoryPercentage 40 | 서버 메모리의 40%를 Oracle에 할당 |
-emConfiguration NONE | Enterprise Manager 설정 안 함 |
-sysPassword ora951753 | SYS 관리자 비밀번호 설정 |
-systemPassword ora951753 | SYSTEM 관리자 비밀번호 설정 |
-createAsContainerDatabase true | CDB(컨테이너 DB) 활성화 |
- General_Purpose.dbc : database options, storage attributes, init.ora 설정값이나 파라미터를 참고할 수 있는 기본 템플릿 파일
728x90
3. 데이터베이스 실행 및 사용자, 테이블 생성, 데이터 생성
- 리스너 실행
netca # (Network Configuration Assistant)는 Oracle Listener를 설정하는 유틸리티
lsnrctl start # 리스너 start
lsnrctl status # 리스너 상태 확인

-- sqlplus / as sysdba 로 sqlplus 접속 후
SELECT NAME, OPEN_MODE FROM V$DATABASE; -- 로 실행중인 DATABASE 확인
CREATE USER C##ERP IDENTIFIED BY 1234 DEFAULT TABLESPACE USERS;
GRANT CONNECT, RESOURCE TO C##ERP;
ALTER USER C##ERP QUOTA UNLIMITED ON USERS;
- 오라클 12c부터는 공통계정앞에 c##을 붙이도록 네이밍 규칙이 바뀜. C## 가 붙는 이유는 12c 버전부터 등장하는 CDB, PDB 개념 때문
- nano 로 테이블, 데이터생성을 위한 SQL 스크립트 파일 생성 (글 맨 아래 해당 스크립트 파일별로 적어놓음)
- sqlplus를 해당 폴더에서 실행 후 @파일명 으로 스크립트 실행

EXEC DBMS_STATS.GATHER_SCHEMA_STATS('C##ERP'); -- 해당 유저의 테이블 통계 업데이트
-- 생성된 테이블 row 수 확인
SELECT table_name, num_rows FROM user_tables WHERE num_rows IS NOT NULL;
4. 테이블 생성, 데이터 생성(PL/SQL) SQL Script
- 테이블 생성 스크립트
/***************************************
****************CUST_COM****************
****************************************/
DROP TABLE "CUST_COM";
CREATE TABLE "CUST_COM" (
"CUST_ID" VARCHAR2(10) NOT NULL,
"CUST_GRP" CHAR(4) NOT NULL,
"NAME" VARCHAR2(30) NOT NULL,
"CNTR_CODE" CHAR(4) NULL,
"CITY_CODE" CHAR(4) NULL,
"POST_CODE" CHAR(5) NULL,
"ADDR1" VARCHAR2(100) NULL,
"ADDR2" VARCHAR2(100) NULL,
"REPR_NAME" VARCHAR(30) NULL,
"BIZ_TYPE" VARCHAR(30) NULL,
"IDST_TYPE" VARCHAR(20) NULL,
"REMK" VARCHAR2(200) NULL,
"STAT" CHAR(1) NULL,
"DEL_FLAG" CHAR(1) NULL,
"CREA_BY" VARCHAR(20) NULL,
"CREA_DATE" DATE NULL,
"UPDT_BY" VARCHAR(20) NULL,
"UPDT_DATE" DATE NULL
);
COMMENT ON COLUMN "CUST_COM"."CUST_ID" IS '고객아이디';
COMMENT ON COLUMN "CUST_COM"."CUST_GRP" IS '고객그룹';
COMMENT ON COLUMN "CUST_COM"."NAME" IS '이름';
COMMENT ON COLUMN "CUST_COM"."CNTR_CODE" IS '국가코드';
COMMENT ON COLUMN "CUST_COM"."CITY_CODE" IS '도시코드';
COMMENT ON COLUMN "CUST_COM"."POST_CODE" IS '우편번호';
COMMENT ON COLUMN "CUST_COM"."ADDR1" IS '주소1';
COMMENT ON COLUMN "CUST_COM"."ADDR2" IS '주소2';
COMMENT ON COLUMN "CUST_COM"."REPR_NAME" IS '대표자이름';
COMMENT ON COLUMN "CUST_COM"."BIZ_TYPE" IS '사업유형';
COMMENT ON COLUMN "CUST_COM"."IDST_TYPE" IS '산업유형';
COMMENT ON COLUMN "CUST_COM"."REMK" IS '비고';
COMMENT ON COLUMN "CUST_COM"."STAT" IS '상태';
COMMENT ON COLUMN "CUST_COM"."DEL_FLAG" IS '삭제플래그';
COMMENT ON COLUMN "CUST_COM"."CREA_BY" IS '생성자';
COMMENT ON COLUMN "CUST_COM"."CREA_DATE" IS '생성일자';
COMMENT ON COLUMN "CUST_COM"."UPDT_BY" IS '수정자';
COMMENT ON COLUMN "CUST_COM"."UPDT_DATE" IS '수정일자';
ALTER TABLE "CUST_COM" ADD CONSTRAINT "PK_CUST_COM" PRIMARY KEY (
"CUST_ID"
);
/***************************************
****************MATR_COM****************
****************************************/
DROP TABLE "MATR_COM";
CREATE TABLE "MATR_COM" (
"MATR_CODE" VARCHAR2(10) NOT NULL,
"MATR_TYPE" CHAR(4) NOT NULL,
"NAME" VARCHAR2(30) NOT NULL,
"DESC" VARCHAR2(100) NULL,
"PRDT_LINE" CHAR(3) NULL,
"BASE_UOM" VARCHAR(5) NULL,
"MATR_HIER" VARCHAR2(30) NULL,
"MATR_HIER_LV1" CHAR(3) NULL,
"MATR_HIER_LV2" CHAR(3) NULL,
"MATR_HIER_LV3" CHAR(3) NULL,
"MATR_HIER_LV4" CHAR(3) NULL,
"MATR_HIER_LV5" CHAR(3) NULL,
"STAT" CHAR(1) NULL,
"DEL_FLAG" CHAR(1) NULL,
"CREA_BY" VARCHAR(20) NULL,
"CREA_DATE" DATE NULL,
"UPDT_BY" VARCHAR(20) NULL,
"UPDT_DATE" DATE NULL
);
COMMENT ON COLUMN "MATR_COM"."MATR_CODE" IS '자재코드';
COMMENT ON COLUMN "MATR_COM"."MATR_TYPE" IS '자재유형';
COMMENT ON COLUMN "MATR_COM"."NAME" IS '이름';
COMMENT ON COLUMN "MATR_COM"."DESC" IS '설명';
COMMENT ON COLUMN "MATR_COM"."PRDT_LINE" IS '제품라인';
COMMENT ON COLUMN "MATR_COM"."BASE_UOM" IS '기본측정단위';
COMMENT ON COLUMN "MATR_COM"."MATR_HIER" IS '자재계층구조';
COMMENT ON COLUMN "MATR_COM"."MATR_HIER_LV1" IS '자재계층구조레벨1';
COMMENT ON COLUMN "MATR_COM"."MATR_HIER_LV2" IS '자재계층구조레벨2';
COMMENT ON COLUMN "MATR_COM"."MATR_HIER_LV3" IS '자재계층구조레벨3';
COMMENT ON COLUMN "MATR_COM"."MATR_HIER_LV4" IS '자재계층구조레벨4';
COMMENT ON COLUMN "MATR_COM"."MATR_HIER_LV5" IS '자재계층구조레벨5';
COMMENT ON COLUMN "MATR_COM"."STAT" IS '상태';
COMMENT ON COLUMN "MATR_COM"."DEL_FLAG" IS '삭제플래그';
COMMENT ON COLUMN "MATR_COM"."CREA_BY" IS '생성자';
COMMENT ON COLUMN "MATR_COM"."CREA_DATE" IS '생성일자';
COMMENT ON COLUMN "MATR_COM"."UPDT_BY" IS '수정자';
COMMENT ON COLUMN "MATR_COM"."UPDT_DATE" IS '수정일자';
ALTER TABLE "MATR_COM" ADD CONSTRAINT "PK_MATR_COM" PRIMARY KEY (
"MATR_CODE"
);
/***************************************
**************SALE_ORD_HEAD*************
****************************************/
DROP TABLE "SALE_ORD_HEAD";
CREATE TABLE "SALE_ORD_HEAD" (
"SALE_ORD_NO" NUMBER(10) NOT NULL,
"SOLD_TO_PTY" VARCHAR2(10) NOT NULL,
"ORD_DATE" DATE NOT NULL,
"ORD_TYPE" CHAR(4) NOT NULL,
"SALE_DEPT" CHAR(3) NULL,
"SALE_OFIS" CHAR(3) NULL,
"SALE_GRP" CHAR(3) NULL,
"DIST_CHAN" CHAR(2) NOT NULL,
"ORD_RESN" CHAR(3) NULL,
"PRIC_DATE" DATE NULL,
"CURR" CHAR(3) NOT NULL,
"PRC_STAT" CHAR(1) NULL,
"RJEC_RESN" CHAR(2) NULL,
"DEL_FLAG" CHAR(1) NULL,
"CREA_BY" VARCHAR(20) NULL,
"CREA_DATE" DATE NULL,
"UPDT_BY" VARCHAR(20) NULL,
"UPDT_DATE" DATE NULL
);
COMMENT ON COLUMN "SALE_ORD_HEAD"."SALE_ORD_NO" IS '영업문서번호';
COMMENT ON COLUMN "SALE_ORD_HEAD"."SOLD_TO_PTY" IS '판매처(고객아이디)';
COMMENT ON COLUMN "SALE_ORD_HEAD"."ORD_DATE" IS '주문일자';
COMMENT ON COLUMN "SALE_ORD_HEAD"."ORD_TYPE" IS '주문유형';
COMMENT ON COLUMN "SALE_ORD_HEAD"."SALE_DEPT" IS '영업부서';
COMMENT ON COLUMN "SALE_ORD_HEAD"."SALE_OFIS" IS '영업오피스';
COMMENT ON COLUMN "SALE_ORD_HEAD"."SALE_GRP" IS '영업그룹';
COMMENT ON COLUMN "SALE_ORD_HEAD"."DIST_CHAN" IS '유통채널';
COMMENT ON COLUMN "SALE_ORD_HEAD"."ORD_RESN" IS '주문사유';
COMMENT ON COLUMN "SALE_ORD_HEAD"."PRIC_DATE" IS '가결결정일';
COMMENT ON COLUMN "SALE_ORD_HEAD"."CURR" IS '통화';
COMMENT ON COLUMN "SALE_ORD_HEAD"."PRC_STAT" IS '처리상태';
COMMENT ON COLUMN "SALE_ORD_HEAD"."RJEC_RESN" IS '거부사유';
COMMENT ON COLUMN "SALE_ORD_HEAD"."DEL_FLAG" IS '삭제플래그';
COMMENT ON COLUMN "SALE_ORD_HEAD"."CREA_BY" IS '생성자';
COMMENT ON COLUMN "SALE_ORD_HEAD"."CREA_DATE" IS '생성일자';
COMMENT ON COLUMN "SALE_ORD_HEAD"."UPDT_BY" IS '수정자';
COMMENT ON COLUMN "SALE_ORD_HEAD"."UPDT_DATE" IS '수정일자';
ALTER TABLE "SALE_ORD_HEAD" ADD CONSTRAINT "PK_SALE_ORD_HEAD" PRIMARY KEY (
"SALE_ORD_NO"
);
ALTER TABLE "SALE_ORD_HEAD" ADD CONSTRAINT "FK_CUST_COM_TO_SALE_ORD_HEAD_1" FOREIGN KEY (
"SOLD_TO_PTY"
)
REFERENCES "CUST_COM" (
"CUST_ID"
);
/***************************************
**************SALE_ORD_ITEM*************
****************************************/
DROP TABLE "SALE_ORD_ITEM";
CREATE TABLE "SALE_ORD_ITEM" (
"ITEM_SEQ" NUMBER(5) NOT NULL,
"SALE_ORD_NO" NUMBER(10) NOT NULL,
"SHIP_TO_PTY" VARCHAR2(10) NOT NULL,
"MATR_CODE" VARCHAR2(10) NOT NULL,
"ITEM_NAME" VARCHAR2(30) NULL,
"PRDT_LINE" CHAR(3) NULL,
"ORD_QTY" NUMBER(18,6) NULL,
"SALE_UOM" VARCHAR(5) NULL,
"NET_VAL" NUMBER(18,6) NULL,
"CURR" CHAR(3) NULL,
"GROS_VAL" NUMBER(18,6) NULL,
"TAX_VAL" NUMBER(18,6) NULL,
"DELV_REQ_DATE" DATE NULL,
"RJEC_RESN" CHAR(2) NULL,
"PRC_STAT" CHAR(1) NULL,
"CREA_BY" VARCHAR(20) NULL,
"CREA_DATE" DATE NULL,
"UPDT_BY" VARCHAR(20) NULL,
"UPDT_DATE" DATE NULL
);
COMMENT ON COLUMN "SALE_ORD_ITEM"."ITEM_SEQ" IS '아이템순번';
COMMENT ON COLUMN "SALE_ORD_ITEM"."SALE_ORD_NO" IS '영업문서번호';
COMMENT ON COLUMN "SALE_ORD_ITEM"."SHIP_TO_PTY" IS '납품처(고객아이디)';
COMMENT ON COLUMN "SALE_ORD_ITEM"."MATR_CODE" IS '자재코드';
COMMENT ON COLUMN "SALE_ORD_ITEM"."ITEM_NAME" IS '아이템이름';
COMMENT ON COLUMN "SALE_ORD_ITEM"."PRDT_LINE" IS '제품라인';
COMMENT ON COLUMN "SALE_ORD_ITEM"."ORD_QTY" IS '주문수량';
COMMENT ON COLUMN "SALE_ORD_ITEM"."SALE_UOM" IS '영업측정단위';
COMMENT ON COLUMN "SALE_ORD_ITEM"."NET_VAL" IS '순가치';
COMMENT ON COLUMN "SALE_ORD_ITEM"."CURR" IS '통화';
COMMENT ON COLUMN "SALE_ORD_ITEM"."GROS_VAL" IS '총가치';
COMMENT ON COLUMN "SALE_ORD_ITEM"."TAX_VAL" IS '세금가치';
COMMENT ON COLUMN "SALE_ORD_ITEM"."DELV_REQ_DATE" IS '납품요청일';
COMMENT ON COLUMN "SALE_ORD_ITEM"."RJEC_RESN" IS '거부사유';
COMMENT ON COLUMN "SALE_ORD_ITEM"."PRC_STAT" IS '처리상태';
COMMENT ON COLUMN "SALE_ORD_ITEM"."CREA_BY" IS '생성자';
COMMENT ON COLUMN "SALE_ORD_ITEM"."CREA_DATE" IS '생성일자';
COMMENT ON COLUMN "SALE_ORD_ITEM"."UPDT_BY" IS '수정자';
COMMENT ON COLUMN "SALE_ORD_ITEM"."UPDT_DATE" IS '수정일자';
ALTER TABLE "SALE_ORD_ITEM" ADD CONSTRAINT "PK_SALE_ORD_ITEM" PRIMARY KEY (
"ITEM_SEQ",
"SALE_ORD_NO"
);
ALTER TABLE "SALE_ORD_ITEM" ADD CONSTRAINT "FK_SALE_ORD_HEAD_TO_SALE_ORD_ITEM_1" FOREIGN KEY (
"SALE_ORD_NO"
)
REFERENCES "SALE_ORD_HEAD" (
"SALE_ORD_NO"
);
ALTER TABLE "SALE_ORD_ITEM" ADD CONSTRAINT "FK_CUST_COM_TO_SALE_ORD_ITEM_1" FOREIGN KEY (
"SHIP_TO_PTY"
)
REFERENCES "CUST_COM" (
"CUST_ID"
);
ALTER TABLE "SALE_ORD_ITEM" ADD CONSTRAINT "FK_MATR_COM_TO_SALE_ORD_ITEM_1" FOREIGN KEY (
"MATR_CODE"
)
REFERENCES "MATR_COM" (
"MATR_CODE"
);
- 고객 공통 정보 테이블(CUST_COM) 데이터 생성
DECLARE
TYPE CompanyArray IS TABLE OF VARCHAR2(100);
company_names CompanyArray := CompanyArray(
'Alpha Corporation', 'Beta Tech', 'Gamma Solutions', 'Delta Enterprises', 'Epsilon Holdings',
'Zeta Innovations', 'Theta Solutions', 'Iota Technologies', 'Kappa Enterprises', 'Lambda Group',
'Mu Systems', 'Nu Consulting', 'Xi Manufacturing', 'Omicron Inc.', 'Pi Enterprises',
'Rho Financials', 'Sigma Tech', 'Tau Solutions', 'Upsilon Logistics', 'Phi Innovations',
'Chi Holdings', 'Psi Retail', 'Omega Consulting', 'AlphaPlus Tech', 'BetaMax Solutions',
'GammaPrime Inc.', 'DeltaX Enterprises', 'EpsilonSoft', 'ZetaPro Consulting', 'ThetaAI',
'Omega Retail', 'Lambda Innovations', 'Kappa Systems', 'Mu Technologies', 'Nu Financials',
'Xi Logistics', 'Omicron Consulting', 'Pi Tech', 'Rho Manufacturing', 'Sigma Retail',
'Tau AI', 'Upsilon Innovations', 'Phi Systems', 'Chi Enterprises', 'Psi Holdings',
'Omega AI', 'AlphaEdge Solutions', 'BetaCore Tech', 'GammaFusion', 'DeltaCloud'
);
v_cust_id VARCHAR2(10);
v_cust_grp CHAR(4);
v_cntr_code CHAR(4);
v_city_code CHAR(4);
v_post_code CHAR(5);
v_addr1 VARCHAR2(100);
v_addr2 VARCHAR2(100);
v_repr_name VARCHAR2(30);
v_biz_type VARCHAR2(30);
v_idst_type VARCHAR2(20);
v_remk VARCHAR2(200);
v_stat CHAR(1);
v_del_flag CHAR(1);
v_crea_by VARCHAR2(20);
v_crea_date DATE;
v_updt_by VARCHAR2(20);
v_updt_date DATE;
BEGIN
FOR i IN 1..company_names.COUNT LOOP
-- 랜덤한 CUST_ID 생성 (CUST_00001 ~ CUST_99999)
v_cust_id := LPAD(TRUNC(DBMS_RANDOM.VALUE(1, 9999999999)), 10, '0');
-- 랜덤한 그룹 코드 (A001 ~ A005)
v_cust_grp := 'A00' || TRUNC(DBMS_RANDOM.VALUE(1, 4));
-- CNTR_CODE (랜덤 국가코드)
v_cntr_code := CASE TRUNC(DBMS_RANDOM.VALUE(1, 6))
WHEN 1 THEN 'KR' WHEN 2 THEN 'US' WHEN 3 THEN 'JP'
WHEN 4 THEN 'CN' WHEN 5 THEN 'SG' ELSE 'DE' END;
-- CITY_CODE (랜덤 도시코드)
v_city_code := CASE v_cntr_code
WHEN 'KR' THEN 'SEO' WHEN 'US' THEN 'NY' WHEN 'JP' THEN 'TKY'
WHEN 'CN' THEN 'SH' WHEN 'SG' THEN 'SIN' ELSE 'BER' END;
-- 랜덤한 우편번호 (10000 ~ 99999)
v_post_code := LPAD(TRUNC(DBMS_RANDOM.VALUE(10000, 99999)), 5, '0');
-- 주소 랜덤 생성
v_addr1 := 'Street ' || TRUNC(DBMS_RANDOM.VALUE(1, 500));
v_addr2 := 'Building ' || TRUNC(DBMS_RANDOM.VALUE(1, 100));
-- 대표자명 및 업종 정보 랜덤
v_repr_name := 'CEO_' || DBMS_RANDOM.STRING('U', 3);
v_biz_type := 'Biz_' || DBMS_RANDOM.STRING('U', 4);
v_idst_type := 'Industry_' || TRUNC(DBMS_RANDOM.VALUE(1, 10));
-- 비고 (REMK) 및 상태 (STAT), 삭제 플래그 (DEL_FLAG)
v_remk := 'Generated by PL/SQL';
-- STAT (A: Active, I: Inactive, D: Deleted 랜덤)
v_stat := CASE TRUNC(DBMS_RANDOM.VALUE(1, 4))
WHEN 1 THEN 'A' ELSE 'I' END;
v_del_flag := '';
-- 생성자, 생성 날짜, 업데이트 정보
v_crea_by := 'System';
v_crea_date := SYSDATE - TRUNC(DBMS_RANDOM.VALUE(1, 365)); -- 최근 1년 내 생성
v_updt_by := 'System';
v_updt_date := v_crea_date + TRUNC(DBMS_RANDOM.VALUE(0, 30)); -- 생성일 이후 랜덤 업데이트
-- 데이터 삽입
INSERT INTO CUST_COM (
CUST_ID, CUST_GRP, NAME, CNTR_CODE, CITY_CODE, POST_CODE,
ADDR1, ADDR2, REPR_NAME, BIZ_TYPE, IDST_TYPE, REMK, STAT,
DEL_FLAG, CREA_BY, CREA_DATE, UPDT_BY, UPDT_DATE
) VALUES (
v_cust_id, v_cust_grp, company_names(i), v_cntr_code, v_city_code, v_post_code,
v_addr1, v_addr2, v_repr_name, v_biz_type, v_idst_type, v_remk, v_stat,
v_del_flag, v_crea_by, v_crea_date, v_updt_by, v_updt_date
);
END LOOP;
-- 커밋
COMMIT;
DBMS_OUTPUT.PUT_LINE('✅ 50개 데이터가 CUST_COM 테이블에 삽입되었습니다.');
END;
/
- 자재 공통 정보 테이블(MATR_COM) 데이터 생성
DELETE MATR_COM;
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1001', 'FNGD', 'Steel Plate', 'Heavy-duty steel plate', 'PLT', 'KG', 'STL', '001', '001', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1002', 'WINP', 'Copper Wire', 'High conductivity copper wire', 'WR', 'M', 'COP', '001', '001', '002', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1003', 'WINP', 'Aluminum Sheet', 'Aluminum alloy sheet', 'ALM', 'M2', 'ALM', '001', '002', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1004', 'FNGD', 'Plastic Pellet', 'Polyethylene pellets for molding', 'PLT', 'KG', 'PLA', '002', '001', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1005', 'FNGD', 'Rubber Mold', 'High-density rubber mold', 'RUB', 'KG', 'RUB', '002', '002', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1006', 'FNGD', 'Iron Rod', 'Solid iron rod for construction', 'CON', 'M', 'IRN', '003', '001', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1007', 'FNGD', 'Cement Bag', 'Portland cement for construction', 'CON', 'KG', 'CEM', '003', '001', '002', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1008', 'WINP', 'Brick', 'Red clay brick for wall construction', 'CON', 'PC', 'BRK', '003', '002', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1009', 'FNGD', 'LED Panel', 'Energy-efficient LED panel', 'ELE', 'EA', 'LED', '004', '001', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1010', 'FNGD', 'Power Supply', '12V power supply for LED lights', 'ELE', 'EA', 'PSU', '004', '002', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1011', 'FNGD', 'Fiber Optic Cable', 'High-speed fiber optic cable', 'TEL', 'M', 'FOC', '005', '001', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1012', 'FNGD', 'Wireless Router', 'High-speed wireless router', 'TEL', 'EA', 'WLR', '005', '001', '002', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1013', 'FNGD', 'Bicycle Frame', 'Aluminum bicycle frame', 'BIK', 'EA', 'BIC', '006', '001', '001', 'A', 'N', 'admin', SYSDATE);
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1014', 'FNGD', 'Bike Tire', 'Durable rubber tire for bicycles', 'BIK', 'EA', 'TIR', '006', '002', '001', 'A', 'N', 'admin', SYSDATE);
-- 서비스 자재 2: 소프트웨어 라이선스
INSERT INTO MATR_COM (MATR_CODE, MATR_TYPE, NAME, "DESC", PRDT_LINE, BASE_UOM, MATR_HIER, MATR_HIER_LV1, MATR_HIER_LV2, MATR_HIER_LV3, STAT, DEL_FLAG, CREA_BY, CREA_DATE)
VALUES ('1015', 'SRVC', 'Software License', 'Annual software license for office suite', 'SVC', 'EA', 'SWL', '008', '002', '001', 'A', 'N', 'admin', SYSDATE);
COMMIT;
UPDATE MATR_COM SET MATR_HIER = MATR_HIER_LV1 || MATR_HIER_LV2 || MATR_HIER_LV1;
COMMIT;
- 주문 헤더 테이블(SALE_ORD_HEAD) 데이터 생성
DECLARE
v_sale_ord_no NUMBER := 1;
v_sold_to_pty VARCHAR2(10);
v_ord_date DATE := TO_DATE('2025-01-01', 'YYYY-MM-DD');
v_ord_type CHAR(4);
v_sale_dept CHAR(3);
v_sale_ofis CHAR(3);
v_dist_chan CHAR(2);
v_ord_resn CHAR(3);
v_curr CHAR(3);
v_prc_stat CHAR(1);
v_del_flag CHAR(1);
TYPE cust_id_table IS TABLE OF VARCHAR2(10);
v_cust_ids cust_id_table;
v_daily_count NUMBER;
v_total_count NUMBER := 0;
CURSOR c_cust IS SELECT CUST_ID FROM CUST_COM;
BEGIN
-- CUST_COM 테이블에서 모든 CUST_ID를 가져와서 배열에 저장
OPEN c_cust;
FETCH c_cust BULK COLLECT INTO v_cust_ids;
CLOSE c_cust;
-- 2025년 1월 1일부터 12월 31일까지 반복
WHILE v_ord_date <= TO_DATE('2025-12-31', 'YYYY-MM-DD') LOOP
-- 하루에 100~200건 생성 (랜덤)
v_daily_count := TRUNC(DBMS_RANDOM.VALUE(150, 300));
FOR i IN 1..v_daily_count LOOP
EXIT WHEN v_total_count >= 100000; -- 10만 건에 근접하면 종료
-- SOLD_TO_PTY 랜덤 선택
v_sold_to_pty := v_cust_ids(TRUNC(DBMS_RANDOM.VALUE(1, v_cust_ids.COUNT + 1)));
-- ORD_TYPE 설정 (비율 9:0.2:0.2:0.2:0.2:0.2)
v_ord_type := CASE
WHEN DBMS_RANDOM.VALUE < 0.9 THEN 'NORM'
WHEN DBMS_RANDOM.VALUE < 0.92 THEN 'FREE'
WHEN DBMS_RANDOM.VALUE < 0.94 THEN 'SRVC'
WHEN DBMS_RANDOM.VALUE < 0.96 THEN 'RETN'
WHEN DBMS_RANDOM.VALUE < 0.98 THEN 'AJCR'
ELSE 'AJDR'
END;
-- SALE_DEPT 설정
v_sale_dept := CASE TRUNC(DBMS_RANDOM.VALUE(1, 5))
WHEN 1 THEN 'A01'
WHEN 2 THEN 'A02'
WHEN 3 THEN 'B01'
ELSE 'B02'
END;
-- SALE_OFIS 설정
v_sale_ofis := CASE v_sale_dept
WHEN 'A01' THEN CASE WHEN DBMS_RANDOM.VALUE < 0.5 THEN '10A' ELSE '11A' END
WHEN 'A02' THEN CASE WHEN DBMS_RANDOM.VALUE < 0.5 THEN '20A' ELSE '21A' END
WHEN 'B01' THEN CASE WHEN DBMS_RANDOM.VALUE < 0.5 THEN '10B' ELSE '11B' END
ELSE CASE WHEN DBMS_RANDOM.VALUE < 0.5 THEN '20B' ELSE '21B' END
END;
-- DIST_CHAN 설정
v_dist_chan := CASE WHEN DBMS_RANDOM.VALUE < 0.5 THEN 'LO' ELSE 'EX' END;
-- ORD_RESN 설정
v_ord_resn := NULL;
IF v_ord_type = 'AJCR' THEN
v_ord_resn := CASE WHEN DBMS_RANDOM.VALUE < 0.5 THEN 'SAL' ELSE 'SDC' END;
ELSIF v_ord_type = 'FREE' THEN
v_ord_resn := CASE WHEN DBMS_RANDOM.VALUE < 0.5 THEN 'SMP' ELSE 'QAN' END;
ELSIF v_ord_type = 'RETN' THEN
IF DBMS_RANDOM.VALUE < 0.5 THEN
v_ord_resn := 'DAM';
END IF;
END IF;
-- CURR 설정
v_curr := CASE WHEN v_dist_chan = 'LO' THEN 'KRW' ELSE 'USD' END;
IF v_ord_date < TO_DATE('2025-12-01', 'YYYY-MM-DD') THEN
v_prc_stat := CASE
WHEN DBMS_RANDOM.VALUE < 0.98 THEN 'D'
ELSE 'E'
END;
ELSE
v_prc_stat := CASE
WHEN DBMS_RANDOM.VALUE < 0.2 THEN 'A'
WHEN DBMS_RANDOM.VALUE < 0.2 THEN 'B'
WHEN DBMS_RANDOM.VALUE < 0.2 THEN 'C'
WHEN DBMS_RANDOM.VALUE < 0.3 THEN 'D'
WHEN DBMS_RANDOM.VALUE < 0.1 THEN 'E'
ELSE 'E'
END;
END IF;
v_del_flag := NULL;
IF v_prc_stat = 'E' AND DBMS_RANDOM.VALUE < 0.5 THEN
v_del_flag := 'Y';
END IF;
-- 데이터 삽입
INSERT INTO SALE_ORD_HEAD (
SALE_ORD_NO, SOLD_TO_PTY, ORD_DATE, ORD_TYPE, SALE_DEPT, SALE_OFIS,
DIST_CHAN, ORD_RESN, CURR, PRIC_DATE, CREA_DATE, PRC_STAT, DEL_FLAG
) VALUES (
v_sale_ord_no, v_sold_to_pty, v_ord_date, v_ord_type, v_sale_dept, v_sale_ofis,
v_dist_chan, v_ord_resn, v_curr, v_ord_date, v_ord_date, v_prc_stat, v_del_flag
);
-- SALE_ORD_NO 증가
v_sale_ord_no := v_sale_ord_no + 1;
v_total_count := v_total_count + 1;
-- 1,000건마다 커밋
IF MOD(v_total_count, 1000) = 0 THEN
COMMIT;
END IF;
END LOOP;
-- ORD_DATE 하루 증가
v_ord_date := v_ord_date + 1;
END LOOP;
-- 마지막 커밋
COMMIT;
END;
/
- 주문 아이템 정보 테이블(SALE_ORD_ITEM) 데이터 생성
DECLARE
TYPE matr_table IS TABLE OF MATR_COM%ROWTYPE;
v_matr_list matr_table;
TYPE sale_ord_table IS TABLE OF SALE_ORD_HEAD%ROWTYPE;
v_sale_orders sale_ord_table;
v_item_seq NUMBER;
v_ship_to_pty VARCHAR2(10);
v_matr_code VARCHAR2(10);
v_item_name VARCHAR2(30);
v_prdt_line CHAR(3);
v_ord_qty NUMBER(18,6);
v_sale_uom VARCHAR2(5);
v_net_val NUMBER(18,6);
v_gros_val NUMBER(18,6);
v_tax_val NUMBER(18,6);
v_delv_req_date DATE;
v_total_count NUMBER := 0;
CURSOR c_sale IS SELECT * FROM SALE_ORD_HEAD;
CURSOR c_matr IS SELECT * FROM MATR_COM;
BEGIN
-- MATR_COM 데이터를 가져와서 메모리에 저장
OPEN c_matr;
FETCH c_matr BULK COLLECT INTO v_matr_list;
CLOSE c_matr;
-- SALE_ORD_HEAD 데이터를 가져와서 메모리에 저장
OPEN c_sale;
FETCH c_sale BULK COLLECT INTO v_sale_orders;
CLOSE c_sale;
-- SALE_ORD_HEAD를 순회하면서 SALE_ORD_ITEM 데이터 삽입
FOR i IN 1..v_sale_orders.COUNT LOOP
-- SALE_ORD_HEAD 정보 가져오기
v_ship_to_pty := v_sale_orders(i).SOLD_TO_PTY;
-- 랜덤한 아이템 개수 (1~5개)
FOR j IN 1..TRUNC(DBMS_RANDOM.VALUE(1,6)) LOOP
v_item_seq := j;
-- MATR_COM에서 랜덤한 데이터 선택
IF v_sale_orders(i).ORD_TYPE = 'SRVC' THEN
-- SRVC일 경우 PRDT_LINE이 'SVC'인 데이터 하나 포함
SELECT MATR_CODE, NAME, PRDT_LINE, BASE_UOM
INTO v_matr_code, v_item_name, v_prdt_line, v_sale_uom
FROM MATR_COM
WHERE PRDT_LINE = 'SVC'
AND ROWNUM = 1;
ELSE
-- 일반적인 경우 랜덤한 제품 선택
v_matr_code := v_matr_list(TRUNC(DBMS_RANDOM.VALUE(1, v_matr_list.COUNT + 1))).MATR_CODE;
v_item_name := v_matr_list(TRUNC(DBMS_RANDOM.VALUE(1, v_matr_list.COUNT + 1))).NAME;
v_prdt_line := v_matr_list(TRUNC(DBMS_RANDOM.VALUE(1, v_matr_list.COUNT + 1))).PRDT_LINE;
v_sale_uom := v_matr_list(TRUNC(DBMS_RANDOM.VALUE(1, v_matr_list.COUNT + 1))).BASE_UOM;
END IF;
-- ORD_QTY 설정
IF v_prdt_line = 'SVC' THEN
v_ord_qty := 1;
ELSE
v_ord_qty := TRUNC(DBMS_RANDOM.VALUE(100, 1001));
END IF;
-- NET_VAL 설정
IF v_sale_orders(i).ORD_TYPE = 'FREE' THEN
v_net_val := 0;
ELSIF v_sale_orders(i).ORD_TYPE = 'RETN' THEN
v_net_val := -1 * v_ord_qty * TRUNC(DBMS_RANDOM.VALUE(10, 100));
ELSE
v_net_val := v_ord_qty * TRUNC(DBMS_RANDOM.VALUE(10, 100));
END IF;
-- GROS_VAL & TAX_VAL 설정
v_gros_val := TRUNC(v_net_val * 1.1);
v_tax_val := v_gros_val - v_net_val;
-- DELV_REQ_DATE 설정 (8:1:1 비율)
v_delv_req_date := v_sale_orders(i).ORD_DATE + CASE
WHEN DBMS_RANDOM.VALUE < 0.8 THEN 0
WHEN DBMS_RANDOM.VALUE < 0.9 THEN 1
ELSE 2
END;
-- 데이터 삽입
INSERT INTO SALE_ORD_ITEM (
ITEM_SEQ, SALE_ORD_NO, SHIP_TO_PTY, MATR_CODE, ITEM_NAME, PRDT_LINE, ORD_QTY,
SALE_UOM, NET_VAL, CURR, GROS_VAL, TAX_VAL, DELV_REQ_DATE,
RJEC_RESN, PRC_STAT, CREA_DATE
) VALUES (
v_item_seq, v_sale_orders(i).SALE_ORD_NO, v_ship_to_pty, v_matr_code, v_item_name, v_prdt_line, v_ord_qty,
v_sale_uom, v_net_val,
CASE WHEN v_sale_orders(i).DIST_CHAN = 'LO' THEN 'KRW' ELSE 'USD' END,
v_gros_val, v_tax_val, v_delv_req_date,
v_sale_orders(i).RJEC_RESN, v_sale_orders(i).PRC_STAT, v_sale_orders(i).CREA_DATE
);
-- 1,000건마다 COMMIT
v_total_count := v_total_count + 1;
IF MOD(v_total_count, 1000) = 0 THEN
COMMIT;
END IF;
END LOOP;
END LOOP;
-- 마지막 COMMIT
COMMIT;
END;
/
728x90
'Computer Science > Database' 카테고리의 다른 글
그림으로 공부하는 오라클 구조 - Ch10,11. 오라클 백업/복구, 백그라운드 프로세스 (0) | 2024.07.25 |
---|---|
그림으로 공부하는 오라클 구조 - Ch9. 리두(Redo)와 언두(Undo)의 동작 (0) | 2024.07.23 |
그림으로 공부하는 오라클 구조 - Ch8. 오라클의 대기와 락 (0) | 2024.07.23 |
그림으로 공부하는 오라클 구조 - Ch7. 오라클의 데이터 구조 (0) | 2024.07.17 |
그림으로 공부하는 오라클 구조 - ch6. 커넥션과 서버 프로세스의 생성 (0) | 2024.07.16 |