From cdb2c37ae30b0d7d209941074b40362fcc2f4b87 Mon Sep 17 00:00:00 2001 From: devmrko Date: Fri, 24 Jul 2026 14:18:19 +0900 Subject: [PATCH] refs #730: add ADB PostgreSQL federation recording scripts --- .../README.md | 137 ++++++++++++++++++ sql/adb/73_hmm_rds_pg_00_precheck.sql | 32 ++++ sql/adb/74_hmm_rds_pg_01_credential.sql | 20 +++ sql/adb/75_hmm_rds_pg_02_acl.sql | 61 ++++++++ sql/adb/76_hmm_rds_pg_03_dblink.sql | 24 +++ sql/adb/77_hmm_rds_pg_04_remote_query.sql | 34 +++++ sql/adb/78_hmm_rds_pg_05_views.sql | 109 ++++++++++++++ sql/adb/79_hmm_rds_pg_06_verify.sql | 86 +++++++++++ sql/adb/80_hmm_rds_pg_99_cleanup.sql | 63 ++++++++ 9 files changed, 566 insertions(+) create mode 100644 docs/design/730-adb-rds-postgres-dblink-demo/README.md create mode 100644 sql/adb/73_hmm_rds_pg_00_precheck.sql create mode 100644 sql/adb/74_hmm_rds_pg_01_credential.sql create mode 100644 sql/adb/75_hmm_rds_pg_02_acl.sql create mode 100644 sql/adb/76_hmm_rds_pg_03_dblink.sql create mode 100644 sql/adb/77_hmm_rds_pg_04_remote_query.sql create mode 100644 sql/adb/78_hmm_rds_pg_05_views.sql create mode 100644 sql/adb/79_hmm_rds_pg_06_verify.sql create mode 100644 sql/adb/80_hmm_rds_pg_99_cleanup.sql diff --git a/docs/design/730-adb-rds-postgres-dblink-demo/README.md b/docs/design/730-adb-rds-postgres-dblink-demo/README.md new file mode 100644 index 0000000..08a2173 --- /dev/null +++ b/docs/design/730-adb-rds-postgres-dblink-demo/README.md @@ -0,0 +1,137 @@ +# HMM ADB-RDS PostgreSQL DB Link 녹화 절차 + +- Redmine: #730 +- 적용 브랜치: `hmm-backoffice` +- 실행 위치: Oracle ADB Database Actions SQL Worksheet +- 실행 사용자: `ADMIN` +- 원격 DB: AWS RDS for PostgreSQL +- 원격 데이터베이스/스키마: `postgres` / `hmm_demo` + +## 1. 목적 + +ADB SQL Worksheet에서 AWS RDS PostgreSQL을 Database Link로 연결하고, HMM 가상 선사 +실적을 Oracle 로컬 View로 노출하는 전 과정을 녹화한다. + +녹화 순서는 다음과 같이 고정한다. + +1. 사전 점검 +2. PostgreSQL 접속 Credential 생성 +3. 대상 호스트 ACL 등록과 조회 +4. Oracle 관리형 PostgreSQL Database Link 생성 +5. 원격 테이블 직접 조회 +6. Select AI에서 사용할 로컬 View와 메타데이터 생성 +7. 행 수와 최신 실적 검증 + +## 2. 기준 자료 + +사내 교육자료를 실행 구문의 1차 기준으로 사용한다. + +- `/Users/joungminko/devkit/fy26_ai/fy26_ai_internal_training/2회차/proxy_database/README.md` +- PostgreSQL 절차: `3.2 PostgreSQL Database 연결` +- 검증된 주의사항: + - `gateway_params`의 `db_type`은 소문자 `postgres` + - `port`는 문자열이 아닌 숫자 `5432` + - PostgreSQL 스키마, 테이블, 컬럼 이름은 큰따옴표로 감싼다. + - Select AI에는 원격 테이블을 직접 등록하지 않고 메타데이터를 부여한 Oracle View를 + 등록한다. + +## 3. 연결값과 객체명 + +| 항목 | 값 | +|---|---| +| RDS host | `database-1.czaaygccsncp.ap-northeast-2.rds.amazonaws.com` | +| RDS port | `5432` | +| PostgreSQL database | `postgres` | +| PostgreSQL user | `postgres` | +| ADB Credential | `HMM_RDS_PG_CRED` | +| ADB Database Link | `HMM_RDS_PG_LINK` | +| 원격 schema | `hmm_demo` | +| 로컬 carrier View | `HMM_RDS_CARRIERS_V` | +| 로컬 월간 실적 View | `HMM_RDS_CARRIER_PERF_V` | +| 로컬 최신 실적 View | `HMM_RDS_CARRIER_LATEST_V` | + +비밀번호는 SQL 파일에 저장하지 않는다. 녹화 직전 Worksheet에 붙여 넣은 Credential +구문의 ``만 실제 값으로 바꾸고, 비밀번호가 보이는 화면은 녹화에서 +가리거나 일시 정지한다. + +운영 전환 시에는 PostgreSQL master 사용자 대신 `hmm_federation_reader`만 상속한 전용 +LOGIN 사용자를 만들어 Credential을 교체한다. + +## 4. ACL의 역할 + +사내 교육자료의 Oracle 관리형 heterogeneous Database Link 절차에는 +`DBMS_NETWORK_ACL_ADMIN` 호출이 포함되지 않는다. DB Link 연결은 +`DBMS_CLOUD_ADMIN.CREATE_DATABASE_LINK`의 관리형 gateway가 수행한다. + +이번 데모의 ACL 스크립트는 요청한 네트워크 통제 절차를 명시적으로 보여주고, `ADMIN`에게 +RDS host의 이름 해석과 5432 포트 연결 권한이 등록되었음을 `DBA_HOST_ACES`로 확인하기 +위한 단계다. 이 ACL을 AWS RDS Security Group 허용이나 관리형 gateway의 출발 IP 허용과 +동일한 것으로 설명하지 않는다. + +- `resolve` ACE: 포트 범위를 지정하지 않는다. +- `connect` ACE: `5432`만 지정한다. +- AWS 측에서는 RDS가 public access 가능해야 하고, Security Group이 Oracle 관리형 + gateway에서 오는 접속을 허용해야 한다. +- 로컬 `global-bundle.pem`은 `psql` 검증용이다. 관리형 DB Link 생성 구문에 업로드하거나 + `directory_name`으로 지정하지 않는다. + +## 5. View 설계 + +### 5.1 `HMM_RDS_CARRIERS_V` + +`hmm_demo.carriers`의 Select AI용 기준정보 View다. PostgreSQL `boolean`과 +`timestamptz` 컬럼은 이번 분석 범위에서 제외해 이기종 타입 변환 변수를 줄인다. + +### 5.2 `HMM_RDS_CARRIER_PERF_V` + +`hmm_demo.carrier_monthly_performance`의 18개월 KPI 144행을 제공한다. 복합 Primary Key는 +`CARRIER_CODE + PERFORMANCE_MONTH`이며 `CARRIER_CODE`는 carrier View를 참조한다는 관계를 +View comment에 기록한다. + +### 5.3 `HMM_RDS_CARRIER_LATEST_V` + +원격 `hmm_demo.carrier_performance_latest_v`를 노출해 2026-07 최신월 선사 8건을 제공한다. + +각 View는 원격 소문자 컬럼을 Oracle의 일반 대문자 식별자로 명시적으로 alias한다. 따라서 +후속 SQL과 Select AI metadata에서는 큰따옴표 없이 안정적으로 사용할 수 있다. + +## 6. 녹화용 실행 파일 + +| 순서 | 파일 | 화면에서 확인할 결과 | +|---|---|---| +| 0 | `73_hmm_rds_pg_00_precheck.sql` | 현재 사용자 `ADMIN`, 기존 객체 유무 | +| 1 | `74_hmm_rds_pg_01_credential.sql` | Credential 1건, 사용자명 `postgres` | +| 2 | `75_hmm_rds_pg_02_acl.sql` | `resolve`, `connect:5432` ACE | +| 3 | `76_hmm_rds_pg_03_dblink.sql` | `HMM_RDS_PG_LINK` 1건 | +| 4 | `77_hmm_rds_pg_04_remote_query.sql` | 선사 8건, 월간 실적 144건 | +| 5 | `78_hmm_rds_pg_05_views.sql` | Oracle 로컬 View 3개 | +| 6 | `79_hmm_rds_pg_06_verify.sql` | `8 / 144 / 8`, 위험도 3종 | +| 재촬영 전 | `80_hmm_rds_pg_99_cleanup.sql` | View, DB Link, Credential만 제거 | + +## 7. 성공 기준 + +- `ALL_CREDENTIALS`에서 `HMM_RDS_PG_CRED`가 조회된다. +- `DBA_HOST_ACES`에서 RDS host의 `resolve`, `connect`가 조회된다. +- `USER_DB_LINKS`에서 `HMM_RDS_PG_LINK`가 조회된다. +- 원격 직접 조회가 선사 8건과 실적 144건을 반환한다. +- 로컬 View 3개가 `VALID` 상태다. +- 최신 View가 8건을 반환하고 `GREEN`, `AMBER`, `RED`가 모두 존재한다. +- Credential password가 SQL 파일, Git diff, 화면 출력에 남지 않는다. + +## 8. 실패 시 판별 + +| 증상 | 우선 확인 | +|---|---| +| `ORA-01031` | `ADMIN`으로 실행했는지 확인 | +| Credential already exists | 재촬영 전 cleanup 실행 여부 확인 | +| Database link already exists | 재촬영 전 cleanup 실행 여부 확인 | +| `ORA-28500`, `ORA-02063`, timeout | RDS 상태, public access, Security Group, endpoint/port 확인 | +| relation does not exist | `"hmm_demo"."..."` 큰따옴표와 객체명 확인 | +| 인증 실패 | Credential의 PostgreSQL 사용자/비밀번호 확인 | +| View comment 대상 오류 | 로컬 View/컬럼은 큰따옴표 없는 대문자 식별자 사용 | + +## 9. 제외 범위 + +- 이번 단계에서는 ADB 직원과 선사의 담당 배정 테이블 및 VPD 정책을 만들지 않는다. +- Select AI profile과 MCP tool 등록은 로컬 View 검증 후 후속 단계에서 수행한다. +- 실제 실행은 녹화를 진행하는 사용자가 SQL Worksheet에서 수행한다. diff --git a/sql/adb/73_hmm_rds_pg_00_precheck.sql b/sql/adb/73_hmm_rds_pg_00_precheck.sql new file mode 100644 index 0000000..dc207ac --- /dev/null +++ b/sql/adb/73_hmm_rds_pg_00_precheck.sql @@ -0,0 +1,32 @@ +-- ============================================================ +-- HMM ADB -> AWS RDS PostgreSQL federation demo +-- Step 0: precheck +-- Run in Database Actions SQL Worksheet as ADMIN. +-- Redmine: #730 +-- ============================================================ + +SELECT + USER AS session_user, + SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') AS current_schema, + SYS_CONTEXT('USERENV', 'DB_NAME') AS database_name +FROM dual; + +SELECT credential_name, username +FROM all_credentials +WHERE credential_name = 'HMM_RDS_PG_CRED'; + +SELECT db_link, username, host, created +FROM user_db_links +WHERE db_link = 'HMM_RDS_PG_LINK'; + +SELECT object_name, object_type, status +FROM user_objects +WHERE object_name IN ( + 'HMM_RDS_CARRIERS_V', + 'HMM_RDS_CARRIER_PERF_V', + 'HMM_RDS_CARRIER_LATEST_V' +) +ORDER BY object_name; + +-- First recording: the last three queries should return no rows. +-- If objects already exist, run 80_hmm_rds_pg_99_cleanup.sql first. diff --git a/sql/adb/74_hmm_rds_pg_01_credential.sql b/sql/adb/74_hmm_rds_pg_01_credential.sql new file mode 100644 index 0000000..40e269b --- /dev/null +++ b/sql/adb/74_hmm_rds_pg_01_credential.sql @@ -0,0 +1,20 @@ +-- ============================================================ +-- Step 1: create the PostgreSQL credential. +-- Run only this statement after replacing in the +-- Worksheet. Never save the actual password in this file. +-- Redmine: #730 +-- ============================================================ + +BEGIN + DBMS_CLOUD.CREATE_CREDENTIAL( + credential_name => 'HMM_RDS_PG_CRED', + username => 'postgres', + password => '' + ); +END; +/ + +-- Passwords are never returned by ALL_CREDENTIALS. +SELECT credential_name, username +FROM all_credentials +WHERE credential_name = 'HMM_RDS_PG_CRED'; diff --git a/sql/adb/75_hmm_rds_pg_02_acl.sql b/sql/adb/75_hmm_rds_pg_02_acl.sql new file mode 100644 index 0000000..4317dd1 --- /dev/null +++ b/sql/adb/75_hmm_rds_pg_02_acl.sql @@ -0,0 +1,61 @@ +-- ============================================================ +-- Step 2: register and verify the host-specific ACL. +-- Run as ADMIN. +-- +-- Important: +-- Oracle-managed heterogeneous Database Link traffic uses the +-- managed gateway. This ACL records SQL-user host permissions; +-- it does not replace the AWS RDS Security Group rule. +-- Redmine: #730 +-- ============================================================ + +-- DNS resolution privilege must not have a port range. +BEGIN + DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( + host => 'database-1.czaaygccsncp.ap-northeast-2.rds.amazonaws.com', + ace => XS$ACE_TYPE( + privilege_list => XS$NAME_LIST('resolve'), + principal_name => SYS_CONTEXT('USERENV', 'SESSION_USER'), + principal_type => XS_ACL.PTYPE_DB + ) + ); +EXCEPTION + WHEN OTHERS THEN + IF SQLCODE != -24243 THEN + RAISE; + END IF; +END; +/ + +-- Permit only the PostgreSQL service port. +BEGIN + DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( + host => 'database-1.czaaygccsncp.ap-northeast-2.rds.amazonaws.com', + lower_port => 5432, + upper_port => 5432, + ace => XS$ACE_TYPE( + privilege_list => XS$NAME_LIST('connect'), + principal_name => SYS_CONTEXT('USERENV', 'SESSION_USER'), + principal_type => XS_ACL.PTYPE_DB + ) + ); +EXCEPTION + WHEN OTHERS THEN + IF SQLCODE != -24243 THEN + RAISE; + END IF; +END; +/ + +SELECT + host, + lower_port, + upper_port, + principal, + privilege, + grant_type +FROM dba_host_aces +WHERE host = 'database-1.czaaygccsncp.ap-northeast-2.rds.amazonaws.com' + AND principal = USER + AND privilege IN ('resolve', 'connect') +ORDER BY privilege, lower_port; diff --git a/sql/adb/76_hmm_rds_pg_03_dblink.sql b/sql/adb/76_hmm_rds_pg_03_dblink.sql new file mode 100644 index 0000000..04b665c --- /dev/null +++ b/sql/adb/76_hmm_rds_pg_03_dblink.sql @@ -0,0 +1,24 @@ +-- ============================================================ +-- Step 3: create an Oracle-managed PostgreSQL Database Link. +-- Based on FY26 internal training, section 3.2.3. +-- Run as ADMIN. +-- Redmine: #730 +-- ============================================================ + +BEGIN + DBMS_CLOUD_ADMIN.CREATE_DATABASE_LINK( + db_link_name => 'HMM_RDS_PG_LINK', + hostname => 'database-1.czaaygccsncp.ap-northeast-2.rds.amazonaws.com', + port => 5432, + service_name => 'postgres', + credential_name => 'HMM_RDS_PG_CRED', + ssl_server_cert_dn => NULL, + private_target => FALSE, + gateway_params => JSON_OBJECT('db_type' VALUE 'postgres') + ); +END; +/ + +SELECT db_link, username, host, created +FROM user_db_links +WHERE db_link = 'HMM_RDS_PG_LINK'; diff --git a/sql/adb/77_hmm_rds_pg_04_remote_query.sql b/sql/adb/77_hmm_rds_pg_04_remote_query.sql new file mode 100644 index 0000000..2f7a7d4 --- /dev/null +++ b/sql/adb/77_hmm_rds_pg_04_remote_query.sql @@ -0,0 +1,34 @@ +-- ============================================================ +-- Step 4: query PostgreSQL directly through the Database Link. +-- PostgreSQL schema, table, view, and column identifiers are +-- lower-case and must be double quoted. +-- Redmine: #730 +-- ============================================================ + +SELECT COUNT(*) AS carrier_count +FROM "hmm_demo"."carriers"@HMM_RDS_PG_LINK; + +SELECT + COUNT(*) AS performance_count, + MIN("performance_month") AS first_month, + MAX("performance_month") AS latest_month +FROM "hmm_demo"."carrier_monthly_performance"@HMM_RDS_PG_LINK; + +SELECT + "carrier_code", + "carrier_name", + "service_region", + "performance_tier" +FROM "hmm_demo"."carriers"@HMM_RDS_PG_LINK +ORDER BY "carrier_code"; + +SELECT + "carrier_code", + "carrier_name", + "performance_month", + "shipped_teu", + "revenue_usd", + "schedule_reliability_pct", + "risk_level" +FROM "hmm_demo"."carrier_performance_latest_v"@HMM_RDS_PG_LINK +ORDER BY "carrier_code"; diff --git a/sql/adb/78_hmm_rds_pg_05_views.sql b/sql/adb/78_hmm_rds_pg_05_views.sql new file mode 100644 index 0000000..b967745 --- /dev/null +++ b/sql/adb/78_hmm_rds_pg_05_views.sql @@ -0,0 +1,109 @@ +-- ============================================================ +-- Step 5: create local Oracle Views and Select AI metadata. +-- Explicit aliases normalize PostgreSQL lower-case identifiers +-- into ordinary Oracle identifiers. +-- Redmine: #730 +-- ============================================================ + +CREATE OR REPLACE VIEW HMM_RDS_CARRIERS_V AS +SELECT + "carrier_code" AS carrier_code, + "carrier_name" AS carrier_name, + "country_code" AS country_code, + "alliance_name" AS alliance_name, + "service_region" AS service_region, + "performance_tier" AS performance_tier +FROM "hmm_demo"."carriers"@HMM_RDS_PG_LINK; + +COMMENT ON TABLE HMM_RDS_CARRIERS_V IS + 'HMM federation demo fictional carrier master. Primary Key: CARRIER_CODE. Referenced by HMM_RDS_CARRIER_PERF_V(CARRIER_CODE).'; +COMMENT ON COLUMN HMM_RDS_CARRIERS_V.CARRIER_CODE IS + 'Primary Key. Fictional carrier identifier such as C001.'; +COMMENT ON COLUMN HMM_RDS_CARRIERS_V.CARRIER_NAME IS + 'Fictional carrier display name; not an actual carrier.'; +COMMENT ON COLUMN HMM_RDS_CARRIERS_V.COUNTRY_CODE IS + 'Two-letter demo country code.'; +COMMENT ON COLUMN HMM_RDS_CARRIERS_V.ALLIANCE_NAME IS + 'Fictional carrier cooperation network.'; +COMMENT ON COLUMN HMM_RDS_CARRIERS_V.SERVICE_REGION IS + 'Primary service region for the demo carrier.'; +COMMENT ON COLUMN HMM_RDS_CARRIERS_V.PERFORMANCE_TIER IS + 'Demo portfolio tier: CORE, GROWTH, or WATCH.'; + +CREATE OR REPLACE VIEW HMM_RDS_CARRIER_PERF_V AS +SELECT + "carrier_code" AS carrier_code, + "performance_month" AS performance_month, + "contracted_teu" AS contracted_teu, + "shipped_teu" AS shipped_teu, + "revenue_usd" AS revenue_usd, + "gross_margin_usd" AS gross_margin_usd, + "schedule_reliability_pct" AS schedule_reliability_pct, + "vessel_utilization_pct" AS vessel_utilization_pct, + "claim_rate_pct" AS claim_rate_pct, + "yoy_growth_pct" AS yoy_growth_pct, + "risk_level" AS risk_level +FROM "hmm_demo"."carrier_monthly_performance"@HMM_RDS_PG_LINK; + +COMMENT ON TABLE HMM_RDS_CARRIER_PERF_V IS + 'HMM federation demo monthly carrier KPI. Composite Primary Key: CARRIER_CODE and PERFORMANCE_MONTH. Foreign Key: CARRIER_CODE references HMM_RDS_CARRIERS_V(CARRIER_CODE). All values are fictional.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.CARRIER_CODE IS + 'Foreign Key referencing HMM_RDS_CARRIERS_V(CARRIER_CODE).'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.PERFORMANCE_MONTH IS + 'First calendar day of the KPI month; part of the composite Primary Key.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.CONTRACTED_TEU IS + 'Contracted container volume in TEU.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.SHIPPED_TEU IS + 'Actually shipped container volume in TEU.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.REVENUE_USD IS + 'Fictional monthly revenue in USD.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.GROSS_MARGIN_USD IS + 'Fictional monthly gross margin in USD; negative values indicate a loss.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.SCHEDULE_RELIABILITY_PCT IS + 'Schedule reliability percentage from 0 through 100.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.VESSEL_UTILIZATION_PCT IS + 'Vessel capacity utilization percentage from 0 through 100.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.CLAIM_RATE_PCT IS + 'Cargo claim rate percentage from 0 through 100.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.YOY_GROWTH_PCT IS + 'Year-over-year performance growth percentage.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_PERF_V.RISK_LEVEL IS + 'Derived demo risk category: GREEN, AMBER, or RED.'; + +CREATE OR REPLACE VIEW HMM_RDS_CARRIER_LATEST_V AS +SELECT + "carrier_code" AS carrier_code, + "carrier_name" AS carrier_name, + "country_code" AS country_code, + "alliance_name" AS alliance_name, + "service_region" AS service_region, + "performance_tier" AS performance_tier, + "performance_month" AS performance_month, + "contracted_teu" AS contracted_teu, + "shipped_teu" AS shipped_teu, + "revenue_usd" AS revenue_usd, + "gross_margin_usd" AS gross_margin_usd, + "schedule_reliability_pct" AS schedule_reliability_pct, + "vessel_utilization_pct" AS vessel_utilization_pct, + "claim_rate_pct" AS claim_rate_pct, + "yoy_growth_pct" AS yoy_growth_pct, + "risk_level" AS risk_level +FROM "hmm_demo"."carrier_performance_latest_v"@HMM_RDS_PG_LINK; + +COMMENT ON TABLE HMM_RDS_CARRIER_LATEST_V IS + 'Latest fictional monthly KPI for each HMM federation demo carrier. Primary Key: CARRIER_CODE.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_LATEST_V.CARRIER_CODE IS + 'Primary Key for the latest carrier KPI row.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_LATEST_V.PERFORMANCE_MONTH IS + 'Latest KPI month available in the PostgreSQL source.'; +COMMENT ON COLUMN HMM_RDS_CARRIER_LATEST_V.RISK_LEVEL IS + 'Latest derived risk category: GREEN, AMBER, or RED.'; + +SELECT object_name, object_type, status +FROM user_objects +WHERE object_name IN ( + 'HMM_RDS_CARRIERS_V', + 'HMM_RDS_CARRIER_PERF_V', + 'HMM_RDS_CARRIER_LATEST_V' +) +ORDER BY object_name; diff --git a/sql/adb/79_hmm_rds_pg_06_verify.sql b/sql/adb/79_hmm_rds_pg_06_verify.sql new file mode 100644 index 0000000..84f5960 --- /dev/null +++ b/sql/adb/79_hmm_rds_pg_06_verify.sql @@ -0,0 +1,86 @@ +-- ============================================================ +-- Step 6: verify the local federation Views. +-- Expected: carrier/performance/latest = 8/144/8. +-- Redmine: #730 +-- ============================================================ + +DECLARE + v_carrier_count PLS_INTEGER; + v_performance_count PLS_INTEGER; + v_latest_count PLS_INTEGER; + v_risk_count PLS_INTEGER; +BEGIN + SELECT COUNT(*) INTO v_carrier_count + FROM HMM_RDS_CARRIERS_V; + + SELECT COUNT(*) INTO v_performance_count + FROM HMM_RDS_CARRIER_PERF_V; + + SELECT COUNT(*), COUNT(DISTINCT risk_level) + INTO v_latest_count, v_risk_count + FROM HMM_RDS_CARRIER_LATEST_V; + + IF v_carrier_count != 8 THEN + RAISE_APPLICATION_ERROR( + -20001, + 'Expected 8 carriers, found ' || v_carrier_count + ); + END IF; + + IF v_performance_count != 144 THEN + RAISE_APPLICATION_ERROR( + -20002, + 'Expected 144 performance rows, found ' || v_performance_count + ); + END IF; + + IF v_latest_count != 8 OR v_risk_count != 3 THEN + RAISE_APPLICATION_ERROR( + -20003, + 'Expected 8 latest rows and 3 risk levels, found ' + || v_latest_count || ' rows and ' || v_risk_count || ' levels' + ); + END IF; +END; +/ + +SELECT + (SELECT COUNT(*) FROM HMM_RDS_CARRIERS_V) AS carrier_count, + (SELECT COUNT(*) FROM HMM_RDS_CARRIER_PERF_V) AS performance_count, + (SELECT COUNT(*) FROM HMM_RDS_CARRIER_LATEST_V) AS latest_count +FROM dual; + +SELECT + MIN(performance_month) AS first_month, + MAX(performance_month) AS latest_month, + COUNT(DISTINCT carrier_code) AS carrier_count +FROM HMM_RDS_CARRIER_PERF_V; + +SELECT risk_level, COUNT(*) AS carrier_count +FROM HMM_RDS_CARRIER_LATEST_V +GROUP BY risk_level +ORDER BY risk_level; + +SELECT + carrier_code, + carrier_name, + performance_month, + shipped_teu, + revenue_usd, + gross_margin_usd, + schedule_reliability_pct, + claim_rate_pct, + risk_level +FROM HMM_RDS_CARRIER_LATEST_V +ORDER BY carrier_code; + +SELECT + table_name, + comments +FROM user_tab_comments +WHERE table_name IN ( + 'HMM_RDS_CARRIERS_V', + 'HMM_RDS_CARRIER_PERF_V', + 'HMM_RDS_CARRIER_LATEST_V' +) +ORDER BY table_name; diff --git a/sql/adb/80_hmm_rds_pg_99_cleanup.sql b/sql/adb/80_hmm_rds_pg_99_cleanup.sql new file mode 100644 index 0000000..27e06d3 --- /dev/null +++ b/sql/adb/80_hmm_rds_pg_99_cleanup.sql @@ -0,0 +1,63 @@ +-- ============================================================ +-- Optional pre-recording reset. +-- Drops only the three local Views, Database Link, and +-- Credential owned by this demo. Host ACL entries are retained. +-- Redmine: #730 +-- ============================================================ + +DECLARE + v_count PLS_INTEGER; +BEGIN + FOR object_row IN ( + SELECT object_name + FROM user_objects + WHERE object_type = 'VIEW' + AND object_name IN ( + 'HMM_RDS_CARRIERS_V', + 'HMM_RDS_CARRIER_PERF_V', + 'HMM_RDS_CARRIER_LATEST_V' + ) + ORDER BY CASE object_name + WHEN 'HMM_RDS_CARRIER_LATEST_V' THEN 1 + WHEN 'HMM_RDS_CARRIER_PERF_V' THEN 2 + ELSE 3 + END + ) LOOP + EXECUTE IMMEDIATE 'DROP VIEW ' || object_row.object_name; + END LOOP; + + SELECT COUNT(*) INTO v_count + FROM user_db_links + WHERE db_link = 'HMM_RDS_PG_LINK'; + + IF v_count = 1 THEN + EXECUTE IMMEDIATE 'DROP DATABASE LINK HMM_RDS_PG_LINK'; + END IF; + + SELECT COUNT(*) INTO v_count + FROM all_credentials + WHERE credential_name = 'HMM_RDS_PG_CRED'; + + IF v_count = 1 THEN + DBMS_CLOUD.DROP_CREDENTIAL( + credential_name => 'HMM_RDS_PG_CRED' + ); + END IF; +END; +/ + +SELECT credential_name, username +FROM all_credentials +WHERE credential_name = 'HMM_RDS_PG_CRED'; + +SELECT db_link, username, host +FROM user_db_links +WHERE db_link = 'HMM_RDS_PG_LINK'; + +SELECT object_name, object_type +FROM user_objects +WHERE object_name IN ( + 'HMM_RDS_CARRIERS_V', + 'HMM_RDS_CARRIER_PERF_V', + 'HMM_RDS_CARRIER_LATEST_V' +);