Files
mars/confluence/Package_Deployment_Guide.md
Grzegorz Michalski 8a162ce9bf dok
2026-02-04 12:21:48 +01:00

2029 lines
70 KiB
Markdown

# Package Deployment Guide - Developer Instructions
## Overview
This guide provides step-by-step instructions for developers on how to properly deploy new package versions using the integrated version tracking and hash-based change detection system.
**Target Audience:** Database developers working with CT_MRDS packages
**System:** Oracle Database 23ai with ENV_MANAGER v3.1.0+
**Last Updated:** 2025-10-22
---
## MANDATORY STANDARDS (NEVER SKIP!)
### 🔴 Critical: Author Field
**ALL scripts MUST have:**
```sql
-- Author: Grzegorz Michalski
```
**❌ WRONG:**
```sql
-- Author: System
-- Author: Developer
-- Author: [your name here]
```
**✅ CORRECT:**
```sql
-- Author: Grzegorz Michalski
```
### 📅 Date Format Standard
**ISO 8601 format only:**
```sql
-- Date: 2026-02-03 (YYYY-MM-DD)
```
### 📝 Script Header Template
**Copy-paste this template for ALL scripts:**
```sql
-- =====================================================================
-- Script: XX_MARS_XXX_description.sql
-- MARS Issue: MARS-XXX
-- Purpose: Brief description of what this script does
-- Author: Grzegorz Michalski
-- Date: YYYY-MM-DD
-- =====================================================================
```
### 🔐 Database User Requirements
**Execute installations as ADMIN:**
```powershell
# ✅ CORRECT
Get-Content "install_marsXXX.sql" | sql "ADMIN/password@service"
# ❌ WRONG
Get-Content "install_marsXXX.sql" | sql "CT_MRDS/password@service"
```
### 🔍 Data Dictionary Views
**Use ALL_* views when installing as ADMIN:**
```sql
-- ✅ CORRECT (ADMIN user)
SELECT * FROM ALL_ERRORS WHERE OWNER = 'CT_MRDS' AND NAME = 'PACKAGE_NAME';
-- ❌ WRONG (shows ADMIN schema, not CT_MRDS)
SELECT * FROM USER_ERRORS WHERE NAME = 'PACKAGE_NAME';
```
### 📂 Log Directory Management
**MANDATORY in all master scripts:**
```sql
-- Create log/ directory before SPOOL (prevents failures)
host mkdir log 2>nul
-- Then configure dynamic SPOOL filename
var filename VARCHAR2(100)
BEGIN
:filename := 'log/INSTALL_MARS_XXX_' || SYS_CONTEXT('USERENV', 'CON_NAME') || '_' || TO_CHAR(SYSDATE,'YYYYMMDD_HH24MISS') || '.log';
END;
/
```
### ✋ User Confirmation
**MANDATORY ACCEPT validation in master scripts:**
```sql
ACCEPT continue CHAR PROMPT 'Type YES to continue with installation, or Ctrl+C to abort: '
WHENEVER SQLERROR EXIT SQL.SQLCODE
BEGIN
IF '&continue' IS NULL OR TRIM('&continue') IS NULL OR UPPER(TRIM('&continue')) != 'YES' THEN
RAISE_APPLICATION_ERROR(-20001, 'Installation aborted by user');
END IF;
END;
/
WHENEVER SQLERROR CONTINUE
```
### 🚪 Clean Exit
**End all master scripts with:**
```sql
spool off
quit; -- ← MANDATORY for clean SQLcl/SQL*Plus exit
```
### 📋 Quick Compliance Checklist
Before committing any script, verify:
- [ ] `Author: Grzegorz Michalski` in header
- [ ] Date in ISO 8601 format (YYYY-MM-DD)
- [ ] Master scripts use `host mkdir log 2>nul`
- [ ] Master scripts require ACCEPT validation
- [ ] Master scripts end with `quit;`
- [ ] Verification queries use ALL_* views with OWNER filter
- [ ] Installation instructions specify ADMIN user
**💡 Remember:** These standards prevent common mistakes and ensure consistency across all MARS packages!
---
## Table of Contents
1. [Before You Start](#before-you-start)
2. [Standard Deployment Workflow](#standard-deployment-workflow)
3. [Version Update Guidelines](#version-update-guidelines)
4. [Deployment Scenarios](#deployment-scenarios)
5. [Creating MARS Installation Packages](#creating-mars-installation-packages)
6. [Troubleshooting](#troubleshooting)
7. [Best Practices](#best-practices)
8. [Quick Reference](#quick-reference)
---
## Before You Start
### Step 0: Prepare Dedicated Working Directory and Git Branch
**CRITICAL:** Before starting work on any MARS package, create a dedicated working directory with its own feature branch:
```powershell
# Navigate to your Git repository parent directory
cd c:\_git\_local_rep
# Clone main repository to new working directory for MARS issue
# This creates complete isolation for the feature branch
git clone working_dir_02 working_dir_02_MARS-XXXX
# Navigate to new working directory
cd working_dir_02_MARS-XXXX
# Ensure you're on main branch and it's up to date
git checkout main
git pull origin main
# Create new feature branch for MARS issue
git checkout -b feature/MARS-XXXX
# Verify you're on the new branch
git branch
# You should see: * feature/MARS-XXXX (asterisk indicates current branch)
```
**Alternative: Git Worktree (Recommended for Advanced Users):**
```powershell
# Navigate to your main Git repository
cd c:\_git\_local_rep\working_dir_02
# Create new worktree with dedicated directory for feature branch
git worktree add ..\working_dir_02_MARS-XXXX feature/MARS-XXXX
# Navigate to new working directory
cd ..\working_dir_02_MARS-XXXX
# Verify you're on the new branch
git branch
```
**Branch and Directory Naming Convention:**
- **Branch Format**: `feature/MARS-XXXX` (e.g., `feature/MARS-1057`)
- **Directory Format**: `working_dir_02_MARS-XXXX` (e.g., `working_dir_02_MARS-1057`)
- Always branch from `main` to ensure clean starting point
- One working directory per MARS issue for complete isolation
**Working Directory Structure (isolated per MARS issue):**
```
c:\_git\_local_rep\
├── working_dir_02\ # Main working directory (main branch)
│ ├── MARS_Packages\
│ ├── database\
│ └── .git\
├── working_dir_02_MARS-1057\ # Dedicated directory for MARS-1057
│ ├── MARS_Packages\
│ │ └── REL01\
│ │ └── MARS-1057\ # New package folder
│ │ ├── rollback_version\
│ │ ├── new_version\
│ │ └── *.sql files
│ ├── database\
│ └── .git\ # Tracks feature/MARS-1057 branch
└── working_dir_02_MARS-1058\ # Dedicated directory for MARS-1058 (parallel work)
└── ...
```
**Git Status Check:**
```powershell
# Always verify which branch and directory you're working in
pwd
# Output should show: c:\_git\_local_rep\working_dir_02_MARS-XXXX
git status
# Output should show: On branch feature/MARS-XXXX
# View all changes in current branch
git status --short
```
**Why dedicated working directories are mandatory:**
- **Complete Isolation**: Each MARS issue has its own physical directory
- **Parallel Work**: Work on multiple MARS issues simultaneously without conflicts
- **Clean Separation**: No risk of mixing changes from different features
- **Testing Safety**: Test different features independently in separate environments
- **Rollback Simplicity**: Delete entire directory to abandon feature
- **Code Review**: Clear separation for pull request workflow
- **Deployment Control**: Deploy from specific working directory with confidence
**Git Worktree Benefits:**
- Shares `.git` repository (saves disk space)
- Faster than full clone
- Automatic branch tracking
- Recommended for experienced Git users
**Cleanup After Merge:**
```powershell
# After feature branch is merged to main, clean up working directory
cd c:\_git\_local_rep
# If using git worktree
git worktree remove working_dir_02_MARS-XXXX
# If using clone, simply delete directory
Remove-Item -Recurse -Force working_dir_02_MARS-XXXX
```
---
### Prerequisites
- **ADMIN user access** - MARS package installations require ADMIN privileges for schema operations
- Access to CT_MRDS schema (or appropriate schema)
- SQLcl or SQL*Plus installed
- Understanding of Semantic Versioning (MAJOR.MINOR.PATCH)
- Package source files available locally
- **Git installed and configured** - Required for version control workflow
**CRITICAL - Data Dictionary Views:**
When installing as ADMIN user, you MUST use `ALL_*` views instead of `USER_*` views for verification queries:
| ❌ WRONG (USER_*) | ✅ CORRECT (ALL_* with OWNER filter) |
|-------------------|--------------------------------------|
| `SELECT * FROM USER_ERRORS WHERE NAME = 'PKG'` | `SELECT * FROM ALL_ERRORS WHERE OWNER = 'CT_MRDS' AND NAME = 'PKG'` |
| `SELECT * FROM USER_OBJECTS WHERE OBJECT_NAME = 'X'` | `SELECT * FROM ALL_OBJECTS WHERE OWNER = 'CT_MRDS' AND OBJECT_NAME = 'X'` |
| `SELECT * FROM USER_TAB_COLUMNS WHERE TABLE_NAME = 'T'` | `SELECT * FROM ALL_TAB_COLUMNS WHERE OWNER = 'CT_MRDS' AND TABLE_NAME = 'T'` |
| `SELECT * FROM USER_TABLES WHERE TABLE_NAME = 'T'` | `SELECT * FROM ALL_TABLES WHERE OWNER = 'CT_MRDS' AND TABLE_NAME = 'T'` |
**Why this matters:** `USER_*` views show objects in the **current schema** (ADMIN). When creating objects in other schemas (ODS, CT_MRDS), you must query `ALL_*` views with explicit OWNER filter to verify the changes.
### System Components
The deployment system uses these key components:
- **ENV_MANAGER** - Centralized version management and hash tracking
- **A_PACKAGE_VERSION_TRACKING** - History table for all package versions
- **CALCULATE_PACKAGE_HASH** - SHA256 hash calculation for change detection
- **TRACK_PACKAGE_VERSION** - Records package versions with automatic change detection
- **CHECK_PACKAGE_CHANGES** - Validates if package was modified
---
## Universal Tracking and Verification Scripts
### MANDATORY: Use Standard Template Files
**CRITICAL:** Every MARS package MUST include two universal scripts for tracking and verification. These scripts are reusable across all MARS issues and provide consistent version management.
#### Required Files Structure
```
MARS_Packages/
└── REL0X/
└── MARS-XXXX/
├── 01_MARS_XXXX_install_*.sql
├── 02_MARS_XXXX_install_*.sql
├── track_package_versions.sql # ✅ MANDATORY - Universal tracking
├── verify_packages_version.sql # ✅ MANDATORY - Universal verification
├── install_marsXXXX.sql # Master script
└── rollback_marsXXXX.sql
```
### track_package_versions.sql
**Purpose:** Universal script for tracking multiple package versions with editable package list.
**Key Features:**
-**Reusable** - Same file for all MARS issues
-**Configurable** - Edit package list array to specify which packages to track
-**Automatic** - Calls ENV_MANAGER.TRACK_PACKAGE_VERSION for each package
-**Summary Output** - Shows tracked packages count and versions
**Template:**
```sql
-- ===================================================================
-- PACKAGE LIST - Edit this array to specify packages to track
-- ===================================================================
vPackageList t_string_array := t_string_array(
'CT_MRDS.DATA_EXPORTER',
'CT_MRDS.FILE_MANAGER',
'ODS.FILE_MANAGER_ODS'
);
-- ===================================================================
```
**Usage in Install Script:**
```sql
PROMPT Step 4: Track Package Versions
PROMPT =========================================================================
@@track_package_versions.sql
```
**Benefits over custom tracking scripts:**
- No hardcoded package names in multiple places
- Single point of configuration
- Consistent error handling
- Standardized output format
- Copy-paste ready for new MARS issues
### verify_packages_version.sql
**Purpose:** Universal script for verifying ALL tracked packages for code changes.
**Key Features:**
-**Automatic Discovery** - Queries A_PACKAGE_VERSION_TRACKING to find all tracked packages
-**Hash Validation** - Calls CHECK_PACKAGE_CHANGES for each package
-**Status Report** - Shows OK or WARNING for each package
-**Zero Configuration** - No editing needed, works automatically
**Usage in Install Script:**
```sql
PROMPT Final Step: Verify All Package Versions
PROMPT =========================================================================
@@verify_packages_version.sql
```
**Output Example:**
```
PACKAGE_OWNER PACKAGE_NAME VERSION STATUS
--------------- ------------------- ---------- -------------------------------
CT_MRDS DATA_EXPORTER 2.2.0 OK: Package has not changed
CT_MRDS FILE_MANAGER 3.3.0 OK: Package has not changed
ODS FILE_MANAGER_ODS 2.1.0 OK: Package has not changed
```
### Master Install Script Structure (MANDATORY)
Every `install_marsXXXX.sql` MUST follow this exact structure:
```sql
-- ===================================================================
-- MARS-XXXX INSTALL SCRIPT
-- ===================================================================
-- Dynamic spool file generation
host mkdir log 2>nul
-- ... spool setup ...
PROMPT Step 1: Deploy Package Specification
@@01_MARS_XXXX_install_PACKAGE_SPEC.sql
PROMPT Step 2: Deploy Package Body
@@02_MARS_XXXX_install_PACKAGE_BODY.sql
PROMPT Step 3: Track Package Versions
@@track_package_versions.sql -- ✅ MANDATORY universal script
PROMPT Step 4: Verify Package Versions
@@verify_packages_version.sql -- ✅ MANDATORY universal script
spool off
quit;
```
### DO NOT Create Custom Track/Verify Scripts
**❌ WRONG (Custom tracking per MARS issue):**
```sql
@@04_MARS_XXXX_track_version.sql -- DON'T DO THIS
@@05_MARS_XXXX_verify_installation.sql -- DON'T DO THIS
```
**✅ CORRECT (Universal scripts):**
```sql
@@track_package_versions.sql -- Always use this
@@verify_packages_version.sql -- Always use this
```
**Why universal scripts are mandatory:**
- **Consistency** - Same behavior across all MARS packages
- **Maintainability** - Bug fixes propagate to all packages
- **Simplicity** - No need to create custom scripts for each issue
- **Compliance** - Ensures all packages follow same standard
- **Code Review** - Easier to review when structure is identical
### Copying Template Files
**For each new MARS package, copy from reference implementation:**
```powershell
# Copy universal scripts from MARS-826-PREHOOK (reference implementation)
Copy-Item "MARS_Packages\REL01_POST_DEACTIVATION\MARS-826-PREHOOK\track_package_versions.sql" `
"MARS_Packages\RELXX\MARS-YYYY\track_package_versions.sql"
Copy-Item "MARS_Packages\REL01_POST_DEACTIVATION\MARS-826-PREHOOK\verify_packages_version.sql" `
"MARS_Packages\RELXX\MARS-YYYY\verify_packages_version.sql"
# Edit package list in track_package_versions.sql
# No changes needed to verify_packages_version.sql (works automatically)
```
---
## Standard Deployment Workflow
### Step 1: Check Current Package Status
Before making any changes, verify the current state:
```sql
-- Connect to database
sql CT_MRDS/password@service_name
-- Check current version
SELECT FILE_MANAGER.GET_VERSION() FROM DUAL;
-- Check for any untracked changes
SELECT ENV_MANAGER.CHECK_PACKAGE_CHANGES('CT_MRDS', 'FILE_MANAGER') FROM DUAL;
```
**Expected Output:** `OK: Package CT_MRDS.FILE_MANAGER has not changed.`
If you see **WARNING**, it means there are untracked modifications. See [Handling Untracked Changes](#handling-untracked-changes).
---
### Step 2: Make Your Code Changes
Edit the package SPEC and/or BODY files in your local workspace:
```
database/CT_MRDS/packages/FILE_MANAGER.pkg
database/CT_MRDS/packages/FILE_MANAGER.pkb
```
**Important:** Do not modify version constants yet.
---
### Step 3: Update Version Information
Based on the type of changes, update version constants in the **SPEC** file:
#### A. Determine Version Increment
Follow Semantic Versioning rules:
- **MAJOR (X.0.0)** - Breaking changes, incompatible API modifications
- **MINOR (x.Y.0)** - New features, backward-compatible additions
- **PATCH (x.y.Z)** - Bug fixes, backward-compatible corrections
#### B. Update Package Constants
Edit the package SPEC file and update three constants:
```sql
-- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH)
PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.3.0'; -- INCREMENT THIS
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-10-22 21:00:00'; -- UPDATE THIS
PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Your Name'; -- YOUR NAME
-- Version History (Latest changes first)
VERSION_HISTORY CONSTANT VARCHAR2(4000) :=
'3.3.0 (2025-10-22): Added new export procedure for historical data' || CHR(13)||CHR(10) || -- ADD THIS LINE
'3.2.0 (2025-10-15): Enhanced validation with column mismatch detection' || CHR(13)||CHR(10) ||
'3.1.0 (2025-10-01): Initial release with file processing capabilities';
```
**Version History Format:**
```
'VERSION (DATE): Brief description of changes' || CHR(13)||CHR(10) ||
```
---
### Step 4: Deploy to Database
Deploy SPEC first, then BODY:
```powershell
# Using PowerShell and SQLcl
Get-Content "database\CT_MRDS\packages\FILE_MANAGER.pkg" | sql "CT_MRDS/password@service_name"
Get-Content "database\CT_MRDS\packages\FILE_MANAGER.pkb" | sql "CT_MRDS/password@service_name"
```
Or using SQL*Plus:
```sql
@database/CT_MRDS/packages/FILE_MANAGER.pkg
@database/CT_MRDS/packages/FILE_MANAGER.pkb
```
**Check for compilation errors:**
```sql
-- When installing as ADMIN, check specific schema
SELECT * FROM ALL_ERRORS
WHERE OWNER = 'CT_MRDS'
AND TYPE IN ('PACKAGE', 'PACKAGE BODY')
AND NAME = 'FILE_MANAGER'
ORDER BY SEQUENCE;
```
---
### Step 5: Track the New Version
After successful deployment, register the new version in the tracking system:
```sql
BEGIN
ENV_MANAGER.TRACK_PACKAGE_VERSION(
pPackageOwner => 'CT_MRDS',
pPackageName => 'FILE_MANAGER',
pPackageVersion => FILE_MANAGER.PACKAGE_VERSION,
pPackageBuildDate => FILE_MANAGER.PACKAGE_BUILD_DATE,
pPackageAuthor => FILE_MANAGER.PACKAGE_AUTHOR
);
END;
/
```
**System Response:**
- If version updated correctly: `First tracking record` or `End TRACK_PACKAGE_VERSION - Record inserted`
- If version NOT updated: `WARNING: Source code changed without version update!`
---
### Step 6: Verify Deployment
Confirm the deployment was successful:
```sql
-- 1. Check deployed version
SELECT FILE_MANAGER.GET_BUILD_INFO() FROM DUAL;
-- 2. Verify no untracked changes
SELECT ENV_MANAGER.CHECK_PACKAGE_CHANGES('CT_MRDS', 'FILE_MANAGER') FROM DUAL;
-- 3. Review tracking history
SELECT
PACKAGE_VERSION,
PACKAGE_BUILD_DATE,
DETECTED_CHANGE_WITHOUT_VERSION,
TO_CHAR(TRACKING_DATE, 'YYYY-MM-DD HH24:MI:SS') AS TRACKED_AT
FROM A_PACKAGE_VERSION_TRACKING
WHERE PACKAGE_OWNER = 'CT_MRDS'
AND PACKAGE_NAME = 'FILE_MANAGER'
ORDER BY TRACKING_DATE DESC
FETCH FIRST 5 ROWS ONLY;
```
---
### Step 7: Update Source Repository (CODE-FIRST Compliance)
**CRITICAL:** After successful database deployment, updated packages MUST be copied back to the main source repository to maintain version control integrity.
```powershell
# Copy updated packages to source repository
# Replace PACKAGE_NAME with actual package name (e.g., FILE_MANAGER)
Copy-Item "database\CT_MRDS\packages\PACKAGE_NAME.pkg" `
"MARS_Packages\mrds_elt-dev-database\mrds_elt-dev-database\database\CT_MRDS\SCHEMA\packages\PACKAGE_NAME.pkg"
Copy-Item "database\CT_MRDS\packages\PACKAGE_NAME.pkb" `
"MARS_Packages\mrds_elt-dev-database\mrds_elt-dev-database\database\CT_MRDS\SCHEMA\packages\PACKAGE_NAME.pkb"
```
**Why this is mandatory:**
- **CODE-FIRST PRINCIPLE**: Source files are the single source of truth
- **Version Control**: Git tracks changes in source repository
- **Team Collaboration**: Other developers need access to latest code
- **Deployment Reproducibility**: Enables clean deployments to other environments
- **Rollback Capability**: Source repository serves as backup
**Directory Structure:**
```
MARS_Packages/
└── mrds_elt-dev-database/
└── mrds_elt-dev-database/
└── database/
├── CT_MRDS/
│ └── SCHEMA/
│ ├── packages/
│ │ ├── FILE_MANAGER.pkg # ← Specification
│ │ ├── FILE_MANAGER.pkb # ← Body
│ │ ├── DATA_EXPORTER.pkg
│ │ ├── DATA_EXPORTER.pkb
│ │ ├── ENV_MANAGER.pkg
│ │ └── ENV_MANAGER.pkb
│ ├── tables/
│ ├── views/
│ └── triggers/
├── ODS/
│ └── SCHEMA/
│ └── packages/
│ ├── FILE_MANAGER_ODS.pkg # ← Specification
│ └── FILE_MANAGER_ODS.pkb # ← Body
└── CT_ET_TEMPLATES/
└── SCHEMA/
└── tables/
```
**Verification:**
```powershell
# Verify files were updated
Get-ChildItem "MARS_Packages\mrds_elt-dev-database\mrds_elt-dev-database\database\CT_MRDS\SCHEMA\packages\*.pkg", `
"MARS_Packages\mrds_elt-dev-database\mrds_elt-dev-database\database\CT_MRDS\SCHEMA\packages\*.pkb" |
Select-Object Name, LastWriteTime |
Sort-Object LastWriteTime -Descending
```
---
## Version Update Guidelines
### Semantic Versioning Rules
| Change Type | Version Impact | Example | Description |
|-------------|---------------|---------|-------------|
| **Breaking Change** | MAJOR (3.0.0 → 4.0.0) | Changed procedure signature, removed parameter | Requires code changes in calling applications |
| **New Feature** | MINOR (3.2.0 → 3.3.0) | Added new procedure, new optional parameter | Backward compatible, adds functionality |
| **Bug Fix** | PATCH (3.2.1 → 3.2.2) | Fixed calculation error, corrected validation | No API changes, fixes existing functionality |
| **Refactoring** | PATCH (3.2.1 → 3.2.2) | Code cleanup, performance optimization | Internal changes only, no behavior change |
### Build Date Format
Always use ISO 8601 format with time:
```sql
PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := 'YYYY-MM-DD HH24:MI:SS';
```
**Example:** `'2025-10-22 21:00:00'`
---
## Deployment Scenarios
### Scenario 1: New Feature Addition (MINOR Version)
**Example:** Adding new export procedure to FILE_MANAGER
1. **Current Version:** 3.2.0
2. **New Version:** 3.3.0
3. **Changes:**
- Add new procedure `EXPORT_HISTORICAL_DATA` to SPEC
- Implement procedure in BODY
- Update `PACKAGE_VERSION` from `'3.2.0'` to `'3.3.0'`
- Update `PACKAGE_BUILD_DATE` to current timestamp
- Add entry to `VERSION_HISTORY`
4. **Deploy & Track:**
```sql
-- Deploy files
@database/CT_MRDS/packages/FILE_MANAGER.pkg
@database/CT_MRDS/packages/FILE_MANAGER.pkb
-- Track new version
BEGIN
ENV_MANAGER.TRACK_PACKAGE_VERSION(
pPackageOwner => 'CT_MRDS',
pPackageName => 'FILE_MANAGER',
pPackageVersion => FILE_MANAGER.PACKAGE_VERSION,
pPackageBuildDate => FILE_MANAGER.PACKAGE_BUILD_DATE,
pPackageAuthor => FILE_MANAGER.PACKAGE_AUTHOR
);
END;
/
```
---
### Scenario 2: Bug Fix (PATCH Version)
**Example:** Fixing date format validation in DATA_EXPORTER
1. **Current Version:** 2.1.0
2. **New Version:** 2.1.1
3. **Changes:**
- Fix validation logic in BODY (no SPEC changes)
- Update `PACKAGE_VERSION` from `'2.1.0'` to `'2.1.1'`
- Update `PACKAGE_BUILD_DATE`
- Add entry to `VERSION_HISTORY`
4. **Deploy & Track:** Same as Scenario 1
---
### Scenario 3: Breaking Change (MAJOR Version)
**Example:** Removing deprecated parameter from FILE_ARCHIVER
1. **Current Version:** 2.5.3
2. **New Version:** 3.0.0
3. **Changes:**
- Remove old parameter from procedure signature in SPEC
- Update BODY implementation
- Update `PACKAGE_VERSION` from `'2.5.3'` to `'3.0.0'`
- Update `PACKAGE_BUILD_DATE`
- Add detailed migration notes to `VERSION_HISTORY`
4. **Additional Steps:**
- Document breaking changes
- Notify dependent application teams
- Update API documentation
---
### Scenario 4: Emergency Hotfix
When urgent fix is needed in production:
1. **Identify Issue:** Document the problem clearly
2. **Create Fix:** Make minimal changes to address the issue
3. **Increment PATCH:** Update to next patch version (e.g., 3.2.5 → 3.2.6)
4. **Fast Track Deployment:**
```powershell
# Quick deployment script
Get-Content "database\CT_MRDS\packages\PACKAGE_NAME.pkg" | sql "CT_MRDS/password@service_name"
Get-Content "database\CT_MRDS\packages\PACKAGE_NAME.pkb" | sql "CT_MRDS/password@service_name"
# Track immediately
echo "BEGIN ENV_MANAGER.TRACK_PACKAGE_VERSION('CT_MRDS', 'PACKAGE_NAME', 'VERSION', 'BUILD_DATE', 'AUTHOR'); END;" | sql "CT_MRDS/password@service_name"
```
5. **Verify & Document:** Record hotfix details in change log
---
## Troubleshooting
### Issue 1: Warning - Untracked Changes Detected
**Symptom:**
```
WARNING: Source code changed without version update!
Last Version: 3.2.0
Current Version: 3.2.0
SPECIFICATION Changed: Hash mismatch detected
```
**Cause:** Code was modified but version constants were not updated.
**Solution:**
1. Update `PACKAGE_VERSION` to next appropriate version
2. Update `PACKAGE_BUILD_DATE` to current timestamp
3. Add entry to `VERSION_HISTORY`
4. Redeploy package
5. Call `TRACK_PACKAGE_VERSION` again
---
### Issue 2: Compilation Errors After Deployment
**Symptom:**
```
Package Body compiled with errors
LINE/COL ERROR
-------- -------------
42/10 PLS-00201: identifier 'PROCEDURE_NAME' must be declared
```
**Solution:**
1. Check `ALL_ERRORS` for detailed error information:
```sql
-- Check specific schema when installing as ADMIN
SELECT LINE, POSITION, TEXT
FROM ALL_ERRORS
WHERE OWNER = 'CT_MRDS' -- Replace with target schema
AND NAME = 'PACKAGE_NAME'
AND TYPE = 'PACKAGE BODY'
ORDER BY SEQUENCE;
```
2. Fix errors in source file
3. Redeploy package
4. Verify compilation: `SELECT * FROM ALL_ERRORS WHERE OWNER = 'CT_MRDS' AND NAME = 'PACKAGE_NAME';`
---
### Issue 3: Package State Discarded Error
**Symptom:**
```
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body has been invalidated
```
**Cause:** Package was recently recompiled, session state needs refresh.
**Solution:** Simply retry the command. This is a transient error that resolves after first execution.
---
### Issue 4: Cannot Track Package - Not Found
**Symptom:**
```
ERROR tracking PACKAGE_NAME: Package not found in database
```
**Solution:**
1. Verify package exists:
```sql
-- Check specific schema when installing as ADMIN
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM ALL_OBJECTS
WHERE OWNER = 'CT_MRDS' -- Replace with target schema
AND OBJECT_NAME = 'PACKAGE_NAME';
```
2. If not found, deploy package first
3. If status = INVALID, recompile package
4. Retry tracking
---
## Creating MARS Installation Packages
### Overview
MARS packages (e.g., MARS-1049, MARS-1011) are deployment packages that bundle database changes for specific features or fixes. They follow a standardized structure with logging, version tracking, and rollback capabilities.
**CRITICAL:** All MARS package installations MUST be executed as **ADMIN user** to ensure proper schema creation, privilege management, and cross-schema operations.
**Installation User Requirements:**
- **User:** ADMIN (required for all MARS installations)
- **Privileges:** Full DBA privileges, CREATE ANY TABLE, ALTER ANY TABLE, EXECUTE on DBMS_CLOUD
- **Connection:** `sql ADMIN/password@service_name`
### Package Structure
**IMPORTANT:** Currently, all new MARS packages are being created in the **REL01** directory. This is the active release folder for ongoing development.
**CRITICAL - .gitignore Configuration:**
Before starting MARS package development, create `.gitignore` file in package root directory to exclude temporary folders from version control:
**File Location:** `MARS_Packages/REL01/MARS-XXXX/.gitignore`
**Required Content:**
```gitignore
# Exclude temporary folders from version control
confluence/
log/
test/
mock_data/
```
**Why exclude these folders:**
- **confluence/**: Working documentation files (may contain drafts, not final versions)
- **log/**: SPOOL log files (generated during installation, environment-specific)
- **test/**: Test artifacts, temporary test data, and test execution logs
- **mock_data/**: Test data files for development and validation (environment-specific)
**What SHOULD be committed:**
- Installation scripts (01_*, 02_*, 91_*, 92_*)
- Master scripts (install_*.sql, rollback_*.sql)
- track_package_versions.sql and verify_packages_version.sql
- README.md
- .gitignore (with standardized exclusions)
- rollback_version/ and new_version/ folders (if package modifications)
- Core deployment files only
Standard MARS package directory structure:
```
MARS_Packages/REL01/MARS-XXXX/
├── .gitignore # Git exclusions (REQUIRED)
├── install_marsXXXX.sql # Master installation script (with SPOOL to log/)
├── rollback_marsXXXX.sql # Master rollback script (with SPOOL to log/)
├── 01_MARS_XXXX_install_*.sql # Individual installation scripts
├── 02_MARS_XXXX_install_*.sql
├── ...
├── 91_MARS_XXXX_rollback_*.sql # Individual rollback scripts (91-99 range)
├── 92_MARS_XXXX_rollback_*.sql
├── track_package_versions.sql # Version tracking script
├── verify_packages_version.sql # Package verification script
├── ...
├── README.md # Package documentation
├── rollback_version/ # Backup of objects BEFORE changes (for rollback)
│ ├── PACKAGE_NAME.pkg # Previous package specification
│ └── PACKAGE_NAME.pkb # Previous package body
├── new_version/ # Updated objects AFTER changes (for installation)
│ ├── PACKAGE_NAME.pkg # New package specification
│ └── PACKAGE_NAME.pkb # New package body
├── test/ # Test files and verification scripts
│ ├── test_marsXXXX.sql # Unit tests
│ ├── TEST_RESULTS.md # Test documentation
│ └── test_data_*.csv # Test data files
├── log/ # SPOOL log files (REQUIRED - auto-created)
│ ├── INSTALL_MARS_XXXX_*.log # Installation logs from SPOOL
│ └── ROLLBACK_MARS_XXXX_*.log # Rollback logs from SPOOL
└── mock_data/ # Mock data for testing (optional)
├── 00_LOAD_ALL_MOCK_DATA.sql # Master data loader
├── 01_load_*.sql # Individual table loaders
└── README.md # Mock data documentation
```
**Naming Conventions:**
- **Installation scripts**: `01-89` range, executed in numerical order
- **Rollback scripts**: `91-99` range, executed in reverse order
- **Verification scripts**: Any number, typically after main scripts
- **Master scripts**: `install_marsXXXX.sql` and `rollback_marsXXXX.sql`
**Version Management Folders (for Database Object Modifications):**
- **`rollback_version/`** - Contains backup of database objects BEFORE changes (for rollback)
- **`new_version/`** - Contains updated database objects AFTER changes (for installation)
**When to use version folders:**
- Required when MARS package modifies ANY existing database objects (packages, tables, views, indexes, triggers, etc.)
- Copy original object definitions to `rollback_version/` before making changes
- Place modified object definitions in `new_version/` after changes
- Examples: FILE_MANAGER.pkg/pkb, A_SOURCE_FILE_CONFIG.sql (table), V_STATUS.sql (view), IDX_CONFIG.sql (index)
**Test Files Organization:**
- **`test/`** - Contains ALL test-related files (unit tests, test data, verification scripts)
- **`log/`** - Contains ALL SPOOL log files from installation/rollback executions (REQUIRED directory)
- **`mock_data/`** - Contains mock data files for development and testing (optional)
- Keep deployment scripts clean - move test artifacts to test/ subfolder after validation
- Include track_package_versions.sql and verify_packages_version.sql in test/ subfolder
- SPOOL log files automatically created in log/ directory by master scripts
- Benefits: Clean deployment structure, easy test replication, organized documentation
---
### Master Install Script Template
All MARS packages MUST include SPOOL logging for audit trail and debugging:
```sql
-- ===================================================================
-- MARS-XXXX INSTALL SCRIPT: Brief Description
-- ===================================================================
-- Purpose: Detailed description of what this package does
-- Author: Grzegorz Michalski
-- Date: YYYY-MM-DD
-- Version: X.Y.Z
-- Dynamic spool file generation (using SYS_CONTEXT - no DBA privileges required)
-- Log files are automatically created in log/ subdirectory
-- IMPORTANT: Ensure log/ directory exists before SPOOL (use host mkdir)
host mkdir log 2>nul
var filename VARCHAR2(100)
BEGIN
:filename := 'log/INSTALL_MARS_XXXX_' || SYS_CONTEXT('USERENV', 'CON_NAME') || '_' || TO_CHAR(SYSDATE,'YYYYMMDD_HH24MISS') || '.log';
END;
/
column filename new_value _filename
select :filename filename from dual;
spool &_filename
SET ECHO OFF
SET TIMING ON
SET SERVEROUTPUT ON SIZE UNLIMITED
SET PAUSE OFF
-- Set current schema context (optional - use when modifying packages in specific schema)
-- ALTER SESSION SET CURRENT_SCHEMA = CT_MRDS;
PROMPT =========================================================================
PROMPT MARS-XXXX: Package Description
PROMPT =========================================================================
PROMPT
PROMPT This script will:
PROMPT - Change 1
PROMPT - Change 2
PROMPT - Change 3
PROMPT
PROMPT Expected Duration: X-Y minutes
PROMPT =========================================================================
-- Confirm installation with user
ACCEPT continue CHAR PROMPT 'Type YES to continue with installation, or Ctrl+C to abort: '
WHENEVER SQLERROR EXIT SQL.SQLCODE
BEGIN
IF '&continue' IS NULL OR TRIM('&continue') IS NULL OR UPPER(TRIM('&continue')) != 'YES' THEN
RAISE_APPLICATION_ERROR(-20001, 'Installation aborted by user');
END IF;
END;
/
WHENEVER SQLERROR CONTINUE
PROMPT
PROMPT =========================================================================
PROMPT Step 1: First Installation Step
PROMPT =========================================================================
@@01_MARS_XXXX_install_step1.sql
PROMPT
PROMPT =========================================================================
PROMPT Step 2: Second Installation Step
PROMPT =========================================================================
@@02_MARS_XXXX_install_step2.sql
-- ... more deployment steps ...
PROMPT
PROMPT =========================================================================
PROMPT Step N: Track Package Versions
PROMPT =========================================================================
@@track_package_versions.sql
PROMPT
PROMPT =========================================================================
PROMPT Final Step: Verify Package Versions
PROMPT =========================================================================
@@verify_packages_version.sql
PROMPT
PROMPT =========================================================================
PROMPT MARS-XXXX Installation - COMPLETED
PROMPT =========================================================================
PROMPT Check the log file for complete installation details.
PROMPT =========================================================================
spool off
quit;
```
**Key Elements:**
1. **Log Directory Creation**: `host mkdir log 2>nul` - Creates log/ directory before SPOOL (suppresses error if exists)
2. **Dynamic Log Name**: `log/INSTALL_MARS_XXXX_<PDB_NAME>_YYYYMMDD_HH24MISS.log` (stored in log/ subdirectory)
3. **SYS_CONTEXT Usage**: Uses `SYS_CONTEXT('USERENV', 'CON_NAME')` instead of `DBA_PDBS` - no DBA privileges required
4. **SPOOL START**: After filename generation, before first PROMPT
5. **SPOOL OFF**: At the very end of the script
6. **SET ECHO OFF**: Prevents double output of PROMPT commands (shows only results, not the SQL commands themselves)
7. **ACCEPT Validation**: User confirmation required before execution (safety feature)
8. **ALTER SESSION SET CURRENT_SCHEMA** (optional): Sets working schema for package operations
9. **@@ Includes**: All sub-scripts executed via `@@` command
10. **track_package_versions.sql**: MANDATORY universal tracking script (must be included before verify)
11. **verify_packages_version.sql**: MANDATORY universal verification script (must be last step before completion)
12. **quit;**: Exits SQLcl/SQL*Plus after completion (important for automated deployments)
**SET ECHO OFF Benefits:**
- **Clean Output**: PROMPT messages appear only once in console and log files
- **Readability**: Log files are easier to read without SQL command echo
- **Professional**: Produces cleaner, more professional-looking installation logs
- **Consistency**: Works the same in both SQLcl and SQL*Plus
- **Sub-Scripts**: Must NOT include `SET ECHO ON` - they inherit setting from master script
**ACCEPT Validation Benefits:**
- **Safety Check**: Prevents accidental execution - requires explicit "YES" confirmation
- **User Control**: User must type YES (case-insensitive) to proceed with changes
- **Abort Capability**: Any other input or Ctrl+C safely aborts before database modifications
- **SQLcl & SQL*Plus Compatible**: Works identically in both tools, unlike PAUSE
- **Best Practice**: Mandatory for both installation and rollback master scripts
**Log File Storage:**
- **Directory**: All SPOOL logs automatically created in `log/` subdirectory
- **Naming Convention**: `log/INSTALL_MARS_XXXX_<PDB>_<timestamp>.log` or `log/ROLLBACK_MARS_XXXX_<PDB>_<timestamp>.log`
- **Auto-Creation**: Directory created by `host mkdir log 2>nul` command before SPOOL (MANDATORY)
- **Error Suppression**: `2>nul` suppresses "directory already exists" errors in PowerShell/Windows
- **Version Control**: Excluded via .gitignore (environment-specific files)
- **Importance**: Without `host mkdir`, SPOOL may fail if log/ directory doesn't exist
**Why `host mkdir log 2>nul` is mandatory:**
- **Reliability**: Ensures log/ directory exists before SPOOL attempts to write
- **Cross-Environment**: Works on fresh Git clones where log/ doesn't exist yet
- **No Errors**: Silently succeeds whether directory exists or not
- **Best Practice**: Prevents installation failures due to missing log directory
- **PowerShell Compatible**: Works in both PowerShell (pwsh.exe) and Windows CMD
---
9. **quit;**: Exits SQLcl/SQL*Plus after completion (important for automated deployments)
**SET ECHO OFF Benefits:**
- **Clean Output**: PROMPT messages appear only once in console and log files
- **Readability**: Log files are easier to read without SQL command echo
- **Professional**: Produces cleaner, more professional-looking installation logs
- **Consistency**: Works the same in both SQLcl and SQL*Plus
- **Sub-Scripts**: Must NOT include `SET ECHO ON` - they inherit setting from master script
**ACCEPT Validation Benefits:**
- **Safety Check**: Prevents accidental execution - requires explicit "YES" confirmation
- **User Control**: User must type YES (case-insensitive) to proceed with changes
- **Abort Capability**: Any other input or Ctrl+C safely aborts before database modifications
- **SQLcl & SQL*Plus Compatible**: Works identically in both tools, unlike PAUSE
- **Best Practice**: Mandatory for both installation and rollback master scripts
---
### Complete MARS Package Example
**MARS-835-PREHOOK** - Real-world example following all standards:
**File Structure:**
```
MARS_Packages/REL01_POST_DEACTIVATION/MARS-835-PREHOOK/
├── .gitignore
├── install_mars835_prehook.sql # Master install (uses universal scripts)
├── rollback_mars835_prehook.sql # Master rollback
├── 01_MARS_835_install_DATA_EXPORTER_SPEC.sql
├── 02_MARS_835_install_DATA_EXPORTER_BODY.sql
├── 91_MARS_835_rollback_DATA_EXPORTER_BODY.sql
├── 92_MARS_835_rollback_DATA_EXPORTER_SPEC.sql
├── track_package_versions.sql # ✅ Universal tracking
├── verify_packages_version.sql # ✅ Universal verification
├── README.md
├── rollback_version/
│ ├── DATA_EXPORTER.pkg # v2.1.1 (before changes)
│ └── DATA_EXPORTER.pkb
├── new_version/
│ ├── DATA_EXPORTER.pkg # v2.2.0 (after changes)
│ └── DATA_EXPORTER.pkb
└── log/ # Auto-created by install script
```
**track_package_versions.sql** (edited for this MARS issue):
```sql
-- ===================================================================
-- PACKAGE LIST - Edit this array to specify packages to track
-- ===================================================================
vPackageList t_string_array := t_string_array(
'CT_MRDS.DATA_EXPORTER' -- Only package modified in MARS-835
);
-- ===================================================================
```
**install_mars835_prehook.sql** (master script):
```sql
-- ===================================================================
-- MARS-835-PREHOOK INSTALL SCRIPT
-- ===================================================================
host mkdir log 2>nul
var filename VARCHAR2(100)
BEGIN
:filename := 'log/INSTALL_MARS_835_PREHOOK_' || SYS_CONTEXT('USERENV', 'CON_NAME') || '_' || TO_CHAR(SYSDATE,'YYYYMMDD_HH24MISS') || '.log';
END;
/
column filename new_value _filename
select :filename filename from dual;
spool &_filename
SET ECHO OFF
SET TIMING ON
SET SERVEROUTPUT ON SIZE UNLIMITED
PROMPT =========================================================================
PROMPT MARS-835-PREHOOK: DRY Refactoring for DATA_EXPORTER
PROMPT =========================================================================
ACCEPT continue CHAR PROMPT 'Type YES to continue: '
WHENEVER SQLERROR EXIT SQL.SQLCODE
BEGIN
IF UPPER(TRIM('&continue')) != 'YES' THEN
RAISE_APPLICATION_ERROR(-20001, 'Installation aborted');
END IF;
END;
/
WHENEVER SQLERROR CONTINUE
PROMPT
PROMPT Step 1: Deploy DATA_EXPORTER Package Specification (v2.2.0)
@@01_MARS_835_install_DATA_EXPORTER_SPEC.sql
PROMPT
PROMPT Step 2: Deploy DATA_EXPORTER Package Body (v2.2.0)
@@02_MARS_835_install_DATA_EXPORTER_BODY.sql
PROMPT
PROMPT Step 3: Track Package Versions
@@track_package_versions.sql
PROMPT
PROMPT Step 4: Verify Package Versions
@@verify_packages_version.sql
PROMPT
PROMPT =========================================================================
PROMPT MARS-835-PREHOOK Installation - COMPLETED
PROMPT =========================================================================
spool off
quit;
```
**Why this is the correct pattern:**
- ✅ Uses universal `track_package_versions.sql` (no custom 04_MARS_835_track_version.sql)
- ✅ Uses universal `verify_packages_version.sql` (no custom 03_MARS_835_verify_installation.sql)
- ✅ Tracking happens AFTER deployment (Step 3)
- ✅ Verification happens LAST (Step 4) to confirm everything is correct
- ✅ Single configuration point (edit package list in track_package_versions.sql)
- ✅ Consistent with ALL other MARS packages
- ✅ Easy to copy/paste for new MARS issues
---
### SPOOL Logging Benefits
**Why SPOOL is mandatory:**
1. **Audit Trail** - Complete record of all installation activities
2. **Debugging** - Capture errors, warnings, and execution details
3. **Compliance** - Required for production deployments
4. **Troubleshooting** - Review what actually happened during installation
5. **Documentation** - Proof of successful deployment
**Log File Contains:**
- All PROMPT messages
- SQL execution results
- Error messages (ORA-XXXXX)
- Timing information
- Package compilation status
- Version tracking confirmations
**Example Log File Name:**
```
log/INSTALL_MARS_1049_ggmichalski_20251126_143052.log
```
**Log Location:** `log/` subdirectory in MARS package root (auto-created by SPOOL)
---
### Creating Individual Installation Scripts
Each numbered script should be self-contained and focused:
**Example: `01_MARS_1049_install_CT_MRDS_ADD_ENCODING_COLUMN.sql`**
```sql
--=============================================================================================================================
-- MARS-1049: Add ENCODING Column to A_SOURCE_FILE_CONFIG Table
--=============================================================================================================================
-- Purpose: Add VARCHAR2(50) ENCODING column with UTF8 default
-- Author: Grzegorz Michalski
-- Date: 2025-11-24
-- Related: MARS-1049 CSV Encoding Support
--=============================================================================================================================
SET SERVEROUTPUT ON
PROMPT ========================================================================
PROMPT Adding ENCODING column to CT_MRDS.A_SOURCE_FILE_CONFIG
PROMPT ========================================================================
-- Add column
ALTER TABLE CT_MRDS.A_SOURCE_FILE_CONFIG
ADD (ENCODING VARCHAR2(50) DEFAULT 'UTF8');
-- Add comment
COMMENT ON COLUMN CT_MRDS.A_SOURCE_FILE_CONFIG.ENCODING IS
'Character encoding for CSV files (e.g., UTF8, WE8MSWIN1252)';
-- Verify change (check specific schema when installing as ADMIN)
SELECT COUNT(*) AS ENCODING_COLUMN_EXISTS
FROM ALL_TAB_COLUMNS
WHERE OWNER = 'CT_MRDS'
AND TABLE_NAME = 'A_SOURCE_FILE_CONFIG'
AND COLUMN_NAME = 'ENCODING';
PROMPT SUCCESS: ENCODING column added to A_SOURCE_FILE_CONFIG
--=============================================================================================================================
-- End of Script
--=============================================================================================================================
```
**Script Best Practices:**
- Clear header with purpose and metadata
- `SET SERVEROUTPUT ON` for debugging
- Descriptive PROMPT messages
- Verification queries after changes
- Success confirmation message
---
### Rollback Script Template
Always provide rollback capability:
```sql
-- ===================================================================
-- MARS-XXXX ROLLBACK SCRIPT: Brief Description
-- ===================================================================
-- Purpose: Rollback all changes from MARS-XXXX installation
-- Author: Grzegorz Michalski
-- Date: YYYY-MM-DD
-- Dynamic spool file generation (using SYS_CONTEXT - no DBA privileges required)
-- IMPORTANT: Ensure log/ directory exists before SPOOL (use host mkdir)
host mkdir log 2>nul
var filename VARCHAR2(100)
BEGIN
:filename := 'log/ROLLBACK_MARS_XXXX_' || SYS_CONTEXT('USERENV', 'CON_NAME') || '_' || TO_CHAR(SYSDATE,'YYYYMMDD_HH24MISS') || '.log';
END;
/
column filename new_value _filename
select :filename filename from dual;
spool &_filename
SET ECHO OFF
SET TIMING ON
SET SERVEROUTPUT ON SIZE UNLIMITED
SET PAUSE OFF
PROMPT =========================================================================
PROMPT MARS-XXXX: Rollback Package
PROMPT =========================================================================
PROMPT This will reverse all changes from MARS-XXXX installation
PROMPT
PROMPT Rollback steps:
PROMPT 1. Restore previous package version
PROMPT 2. Remove added columns/tables
PROMPT 3. Revert configuration changes
PROMPT =========================================================================
-- Confirm rollback with user
ACCEPT continue CHAR PROMPT 'Type YES to continue with rollback, or Ctrl+C to abort: '
WHENEVER SQLERROR EXIT SQL.SQLCODE
BEGIN
IF '&continue' IS NULL OR TRIM('&continue') IS NULL OR UPPER(TRIM('&continue')) != 'YES' THEN
RAISE_APPLICATION_ERROR(-20001, 'Rollback aborted by user');
END IF;
END;
/
WHENEVER SQLERROR CONTINUE
-- Execute rollback scripts in REVERSE order
@@92_MARS_XXXX_rollback_step2.sql
@@91_MARS_XXXX_rollback_step1.sql
PROMPT
PROMPT =========================================================================
PROMPT MARS-XXXX Rollback - COMPLETED
PROMPT =========================================================================
spool off
```
**Rollback Principles:**
- Execute scripts in **REVERSE order** (92, 91, not 91, 92)
- Undo changes from newest to oldest
- Restore previous package versions
- Remove added columns/tables
- Revert configuration changes
- Include verification step after rollback (@@verify_packages_version.sql)
**Rollback Communication Style:**
-**DO**: Use calm, professional tone describing what will be done
-**DO**: List specific rollback steps clearly
-**DON'T**: Use dramatic words like "WARNING", "CRITICAL IMPACT", "DANGER"
-**DON'T**: Create panic - rollback is a normal part of deployment process
- **Rationale**: Rollbacks happen when installations fail or need to be reversed. This is a standard procedure, not an emergency.
**Example - Professional vs. Dramatic:**
```sql
-- ✅ CORRECT - Professional and Clear
PROMPT This will reverse all changes from MARS-828 installation
PROMPT
PROMPT Rollback steps:
PROMPT 1. Remove validation trigger
PROMPT 2. Drop ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS columns
PROMPT 3. Restore FILE_ARCHIVER package to v2.0.0
-- ❌ WRONG - Unnecessarily Dramatic
PROMPT WARNING: This will restore FILE_ARCHIVER to v2.0.0
PROMPT
PROMPT CRITICAL IMPACT:
PROMPT 1. All archival strategies revert to THRESHOLD_BASED
PROMPT 2. ARCHIVAL_STRATEGY and MINIMUM_AGE_MONTHS columns will be dropped
```
---
### Version Tracking Integration
Every MARS package should track package versions using the universal tracking script:
**Recommended Approach: Universal Tracking Script**
```sql
-- ===================================================================
-- Simple Package Version Tracking Script
-- ===================================================================
-- Purpose: Track specified Oracle package versions
-- Author: Grzegorz Michalski
-- Date: 2025-11-26
-- Version: 3.1.0 - List-Based Edition
--
-- USAGE:
-- 1. Edit package list below (add/remove packages as needed)
-- 2. Include in your install/rollback script: @@track_package_versions.sql
-- ===================================================================
SET SERVEROUTPUT ON;
DECLARE
TYPE t_package_rec IS RECORD (
owner VARCHAR2(50),
package_name VARCHAR2(50),
version VARCHAR2(50)
);
TYPE t_packages IS TABLE OF t_package_rec;
TYPE t_string_array IS TABLE OF VARCHAR2(100);
-- ===================================================================
-- PACKAGE LIST - Edit this array to specify packages to track
-- ===================================================================
-- Add or remove entries as needed for your MARS issue
-- Format: 'SCHEMA.PACKAGE_NAME'
-- ===================================================================
vPackageList t_string_array := t_string_array(
'CT_MRDS.FILE_MANAGER',
'ODS.FILE_MANAGER_ODS'
);
-- ===================================================================
vPackages t_packages := t_packages();
vVersion VARCHAR2(50);
vCount NUMBER := 0;
vOwner VARCHAR2(50);
vPackageName VARCHAR2(50);
vDotPos NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE('========================================');
DBMS_OUTPUT.PUT_LINE('Package Version Tracking');
DBMS_OUTPUT.PUT_LINE('========================================');
-- Process each package in the list
FOR i IN 1..vPackageList.COUNT LOOP
vDotPos := INSTR(vPackageList(i), '.');
IF vDotPos > 0 THEN
vOwner := SUBSTR(vPackageList(i), 1, vDotPos - 1);
vPackageName := SUBSTR(vPackageList(i), vDotPos + 1);
-- Get package version
BEGIN
EXECUTE IMMEDIATE 'SELECT ' || vOwner || '.' || vPackageName || '.GET_VERSION() FROM DUAL' INTO vVersion;
vPackages.EXTEND;
vPackages(vPackages.COUNT).owner := vOwner;
vPackages(vPackages.COUNT).package_name := vPackageName;
vPackages(vPackages.COUNT).version := vVersion;
-- Track in ENV_MANAGER
BEGIN
CT_MRDS.ENV_MANAGER.TRACK_PACKAGE_VERSION(
pPackageOwner => vOwner,
pPackageName => vPackageName,
pPackageVersion => vVersion,
pPackageBuildDate => TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'),
pPackageAuthor => 'Grzegorz Michalski'
);
vCount := vCount + 1;
EXCEPTION
WHEN OTHERS THEN NULL; -- Continue even if tracking fails
END;
EXCEPTION
WHEN OTHERS THEN NULL; -- Skip packages that fail
END;
END IF;
END LOOP;
-- Display results
IF vPackages.COUNT > 0 THEN
DBMS_OUTPUT.PUT_LINE('Packages tracked: ' || vCount || ' of ' || vPackages.COUNT);
DBMS_OUTPUT.PUT_LINE('');
FOR i IN 1..vPackages.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(vPackages(i).owner || '.' || vPackages(i).package_name || ' = ' || vPackages(i).version);
END LOOP;
ELSE
DBMS_OUTPUT.PUT_LINE('No packages found in list');
END IF;
DBMS_OUTPUT.PUT_LINE('========================================');
END;
/
```
**Key Benefits:**
- **List-Based**: Simply edit the `vPackageList` array to add/remove packages
- **Automatic Version Detection**: Calls `GET_VERSION()` for each package
- **Error Tolerant**: Continues even if individual packages fail
- **Summary Output**: Shows which packages were successfully tracked
- **Reusable**: Same script can be used across all MARS packages
---
### Package Verification Script
Every MARS package should include a universal verification script to check all tracked packages for untracked changes:
**Recommended: `verify_packages_version.sql`**
```sql
-- ===================================================================
-- Universal Package Version Verification Script
-- ===================================================================
-- Purpose: Verify all tracked Oracle packages for code changes
-- Author: Grzegorz Michalski
-- Date: 2025-11-25
-- Version: 1.0.0
--
-- USAGE:
-- Include at the end of install/rollback scripts: @@verify_packages_version.sql
--
-- OUTPUT:
-- - List of all tracked packages with their current status
-- - OK: Package has not changed since last tracking
-- - WARNING: Package code changed without version update
-- ===================================================================
SET LINESIZE 200
SET PAGESIZE 1000
SET FEEDBACK OFF
PROMPT
PROMPT ========================================
PROMPT Package Version Verification
PROMPT ========================================
PROMPT
COLUMN PACKAGE_OWNER FORMAT A15
COLUMN PACKAGE_NAME FORMAT A20
COLUMN VERSION FORMAT A10
COLUMN STATUS FORMAT A80
SELECT
PACKAGE_OWNER,
PACKAGE_NAME,
PACKAGE_VERSION AS VERSION,
CT_MRDS.ENV_MANAGER.CHECK_PACKAGE_CHANGES(PACKAGE_OWNER, PACKAGE_NAME) AS STATUS
FROM (
SELECT
PACKAGE_OWNER,
PACKAGE_NAME,
PACKAGE_VERSION,
ROW_NUMBER() OVER (PARTITION BY PACKAGE_OWNER, PACKAGE_NAME ORDER BY TRACKING_DATE DESC) AS RN
FROM CT_MRDS.A_PACKAGE_VERSION_TRACKING
)
WHERE RN = 1
ORDER BY PACKAGE_OWNER, PACKAGE_NAME;
PROMPT
PROMPT ========================================
PROMPT Verification Complete
PROMPT ========================================
PROMPT
PROMPT Legend:
PROMPT OK - Package has not changed since last tracking
PROMPT WARNING - Package code changed without version update
PROMPT
PROMPT For detailed hash information, use:
PROMPT SELECT ENV_MANAGER.GET_PACKAGE_HASH_INFO('OWNER', 'PACKAGE') FROM DUAL;
PROMPT ========================================
SET FEEDBACK ON
```
**Key Features:**
- **Universal**: Checks ALL packages in A_PACKAGE_VERSION_TRACKING table
- **Latest Version**: Uses ROW_NUMBER() to get most recent tracking record for each package
- **Status Display**: Shows OK or WARNING for each package
- **Formatted Output**: Clean, readable table format with column alignment
- **Reusable**: Same script works for all MARS packages without modification
- **Legend**: Includes helpful legend explaining OK vs WARNING status
**Usage in Master Scripts:**
```sql
PROMPT
PROMPT === Step 3: Verify all tracked packages ===
@@verify_packages_version.sql
```
**Benefits over Package-Specific Verification:**
- No need to edit script for each MARS package
- Automatically detects all tracked packages
- Consistent verification across all installations
- Easier to maintain (single script for all packages)
---
### Package README Template
Every MARS package MUST include README.md:
```markdown
# MARS-XXXX: Brief Description
## Overview
Detailed description of what this package does and why it's needed.
## Contents
- `install_marsXXXX.sql` - Master installation script with SPOOL logging
- `rollback_marsXXXX.sql` - Master rollback script
- `01_MARS_XXXX_*.sql` - Individual installation scripts
- `91_MARS_XXXX_*.sql` - Individual rollback scripts
## Prerequisites
- Oracle Database 23ai
- Required package versions (e.g., ENV_MANAGER v3.1.0+)
- Schema privileges needed
## Installation
### Option 1: Master Script (Recommended)
```powershell
# IMPORTANT: Execute as ADMIN user for proper privilege management
Get-Content "MARS_Packages/REL01/MARS-XXXX/install_marsXXXX.sql" | sql "ADMIN/password@service"
# Log file created: INSTALL_MARS_XXXX_<PDB>_<timestamp>.log
```
### Option 2: Individual Scripts
```powershell
# IMPORTANT: Execute as ADMIN user
Get-Content "01_MARS_XXXX_*.sql" | sql "ADMIN/password@service"
Get-Content "02_MARS_XXXX_*.sql" | sql "ADMIN/password@service"
# ... etc
```
## Verification
```sql
-- Verify package versions
SELECT PACKAGE_NAME.GET_VERSION() FROM DUAL;
-- Check for errors (ADMIN user checks specific schema)
SELECT * FROM ALL_ERRORS
WHERE OWNER = 'CT_MRDS' -- Replace with target schema
AND NAME = 'PACKAGE_NAME';
```
## Rollback
```powershell
# IMPORTANT: Execute as ADMIN user
Get-Content "MARS_Packages/REL01/MARS-XXXX/rollback_marsXXXX.sql" | sql "ADMIN/password@service"
```
## Expected Changes
- Package X: v1.0.0 → v1.1.0
- Table Y: Added COLUMN_Z
- Configuration: Updated DEFAULT_VALUE
## Testing
Describe how to test the changes after installation.
## Known Issues
List any known limitations or issues.
## Related
- MARS-YYYY: Related package
- Confluence: Link to detailed documentation
```
---
### MARS Package Checklist
Before creating a MARS package, ensure:
- [ ] **Directory Structure**: Created `log/` and `mock_data/` subdirectories (if needed)
- [ ] **.gitignore file**: Created with standardized exclusions (confluence/, log/, test/, mock_data/)
- [ ] **Author field**: All scripts have `Author: Grzegorz Michalski`
- [ ] **ADMIN user**: All installation instructions specify ADMIN user connection
- [ ] All individual scripts numbered correctly (01-89, 91-99)
- [ ] Master install script includes SPOOL logging to `log/` directory
- [ ] Master rollback script includes SPOOL logging to `log/` directory
- [ ] SPOOL filenames use dynamic PDB name and timestamp with `log/` prefix
- [ ] **ACCEPT validation**: Master scripts require explicit "YES" confirmation
- [ ] **quit; command**: Master scripts end with quit; for clean exit
- [ ] All scripts have proper headers with metadata
- [ ] Version tracking scripts included (in test/ subfolder)
- [ ] Verification scripts confirm changes (in test/ subfolder)
- [ ] README.md documents installation process
- [ ] Rollback scripts reverse all changes
- [ ] Rollback includes verification step (@@test/verify_packages_version.sql)
- [ ] **rollback_version/ folder**: Contains backup of objects before changes (if modifying packages)
- [ ] **new_version/ folder**: Contains updated objects after changes (if modifying packages)
- [ ] **test/ folder**: All test files and verification scripts organized in subfolder
- [ ] **log/ folder**: SPOOL log files automatically created by master scripts
- [ ] **mock_data/ folder**: Mock data files organized (if applicable)
- [ ] Tested in DEV environment
- [ ] Log files reviewed for errors (in log/ subdirectory)
- [ ] **Source repository updated**: Changed packages copied to `MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/`
- [ ] Git commit with descriptive message (log/, mock_data/ excluded via .gitignore)
---
### Example 1: Complete MARS-1046 Package (Package Modification)
Real-world example from MARS-1046 (ISO 8601 Date Format Fix):
**Structure:**
```
MARS_Packages/REL01/MARS-1046/
├── install_mars1046.sql # Master with SPOOL, ACCEPT, quit;
├── rollback_mars1046.sql # Master rollback with ACCEPT, quit;
├── 01_MARS_1046_install_CT_MRDS_FILE_MANAGER_SPEC.sql
├── 02_MARS_1046_install_CT_MRDS_FILE_MANAGER_BODY.sql
├── 91_MARS_1046_rollback_CT_MRDS_FILE_MANAGER_BODY.sql
├── 92_MARS_1046_rollback_CT_MRDS_FILE_MANAGER_SPEC.sql
├── track_package_versions.sql # Version tracking
├── verify_packages_version.sql # Package verification
├── README.md # Comprehensive documentation
├── rollback_version/ # v3.3.0 backup for rollback
│ ├── FILE_MANAGER.pkg
│ └── FILE_MANAGER.pkb
├── new_version/ # v3.3.1 updated packages
│ ├── FILE_MANAGER.pkg
│ └── FILE_MANAGER.pkb
├── test/ # All test artifacts
│ ├── test_mars1046.sql # Unit tests (7/7 passed)
│ ├── TEST_RESULTS.md # Test documentation
│ ├── iso8601_test_data.csv # Test data (full format)
│ ├── iso8601_test_data_simple.csv # Test data (simple format)
│ ├── create_iso8601_test_template.sql # Template table creation
│ ├── configure_iso8601_test.sql # Date format configuration
│ ├── process_iso8601_test.sql # E2E test
│ └── INSTALL_MARS_1046_*.log # Log files (3 iterations)
└── log/ # Optional log storage
```
**Key Features:**
- SPOOL logging: `INSTALL_MARS_1046_<PDB>_<timestamp>.log`
- ACCEPT validation: Requires explicit "YES" to proceed (both install & rollback)
- quit; command: Clean SQLcl exit after completion
- Version folders: rollback_version/ (v3.3.0) and new_version/ (v3.3.1)
- Test subfolder: All test files organized separately
- 4-step workflow: Install packages → Track version → Verify packages → quit
- Full rollback: Restore to previous version with verification
- Comprehensive README: Problem, solution, testing, verification
- Track & verify scripts: Universal scripts work for any package
---
### Example 2: Complete MARS-1049-ADHOC Package (Configuration Change)
Real-world example from MARS-1049-ADHOC (CSDB External Tables):
**Structure:**
```
MARS_Packages/REL01/MARS-1049-ADHOC/
├── install_mars1049_adhoc.sql # Master with SPOOL
├── 00_MARS_1049_ADHOC_update_encoding.sql # Update config
├── 01_MARS_1049_ADHOC_drop_external_tables.sql # Drop tables
├── 02_MARS_1049_ADHOC_recreate_external_tables.sql # Recreate with encoding
├── 03_MARS_1049_ADHOC_verify_external_tables.sql # Verify creation
└── README.md # Documentation
```
**Key Features:**
- SPOOL logging: `INSTALL_MARS_1049_ADHOC_<PDB>_<timestamp>.log`
- Numbered sequence: 00 → 01 → 02 → 03
- No rollback (external tables are metadata-only)
- No version folders (no package modifications)
- Verification included
- Clear README with installation options
---
## Post-Installation File Organization
### Organizing Test Files and Logs
After successful installation and verification, organize files for clean Git commit:
**Step 1: Create test/ subfolder**
```powershell
# Create test directory if it doesn't exist
New-Item -ItemType Directory -Force -Path "test" | Out-Null
```
**Step 2: Move test-related files**
```powershell
# Move test scripts and data
Move-Item -Path "test_*.sql" -Destination "test" -Force
Move-Item -Path "*_test_*.csv" -Destination "test" -Force
Move-Item -Path "TEST_RESULTS.md" -Destination "test" -Force
```
**Step 3: Move log files**
```powershell
# Option 1: Move to test/ subfolder
Move-Item -Path "*.log" -Destination "test" -Force
# Option 2: Create dedicated log/ subfolder
New-Item -ItemType Directory -Force -Path "log" | Out-Null
Move-Item -Path "*.log" -Destination "log" -Force
```
**Step 4: Verify clean structure**
```powershell
# Check root directory - should only have deployment scripts and README
Get-ChildItem | Where-Object { $_.Name -notmatch "^(01|02|91|92|install|rollback|README|rollback_version|new_version|test|log)" }
# Expected: No output (all non-deployment files moved)
```
**Final MARS Package Structure:**
```
MARS_Packages/REL01/MARS-XXXX/
├── install_marsXXXX.sql # Master installation
├── rollback_marsXXXX.sql # Master rollback
├── 01_MARS_XXXX_*.sql # Installation scripts
├── 02_MARS_XXXX_*.sql
├── 91_MARS_XXXX_*.sql # Rollback scripts
├── 92_MARS_XXXX_*.sql
├── track_package_versions.sql
├── verify_packages_version.sql
├── README.md # Documentation
├── rollback_version/ # Backup packages
├── new_version/ # Updated packages
└── test/ # ALL test artifacts
├── test_marsXXXX.sql
├── TEST_RESULTS.md
├── *.csv (test data)
```
**Benefits:**
- **Clean Git commits**: Only deployment-relevant files in root
- **Easy testing**: All test materials in one place
- **Reproducibility**: Test setup can be recreated from test/ folder
- **Documentation**: Log files preserved for troubleshooting
- **Professional**: Organized structure for code review
---
## Best Practices
### 1. Always Update Version Before Deployment
**DO:**
```sql
-- Update version first, then deploy
PACKAGE_VERSION := '3.3.0'; -- Updated
PACKAGE_BUILD_DATE := '2025-10-22 21:00:00'; -- Updated
VERSION_HISTORY := '3.3.0 (2025-10-22): New feature...' || CHR(13)||CHR(10) || ...
```
**DON'T:**
```sql
-- Deploy changes without updating version
-- This triggers "untracked changes" warning
```
---
### 2. Use Descriptive Version History
**DO:**
```sql
'3.3.0 (2025-10-22): Added EXPORT_HISTORICAL_DATA procedure for Parquet exports with Hive partitioning'
```
**DON'T:**
```sql
'3.3.0 (2025-10-22): Updates' -- Too vague
```
---
### 3. Deploy SPEC Before BODY
**Correct Order:**
1. Deploy PACKAGE.pkg (specification)
2. Deploy PACKAGE.pkb (body)
3. Track version
**Rationale:** BODY depends on SPEC, deploying SPEC first ensures clean compilation.
---
### 4. Test Before Production Deployment
1. Deploy to DEV environment first
2. Run unit tests
3. Verify functionality
4. Check for performance issues
5. Deploy to PROD only after validation
---
### 5. Document Breaking Changes
For MAJOR version increments, always document:
- What changed
- Why it changed
- Migration path for existing code
- Example of old vs new usage
---
### 6. Use Batch Deployment Scripts
For multiple packages, create deployment script:
```powershell
# deploy_all_packages.ps1
$packages = @('ENV_MANAGER', 'FILE_MANAGER', 'DATA_EXPORTER', 'FILE_ARCHIVER')
foreach ($pkg in $packages) {
Write-Host "Deploying $pkg..."
Get-Content "database\CT_MRDS\packages\${pkg}.pkg" | sql "CT_MRDS/password@service"
Get-Content "database\CT_MRDS\packages\${pkg}.pkb" | sql "CT_MRDS/password@service"
}
# Track all packages
Get-Content "database\scripts\track_all_packages.sql" | sql "CT_MRDS/password@service"
```
---
### 7. Regular Change Detection Audits
Run periodic checks to catch untracked modifications:
```sql
-- Check all packages for changes
@database/scripts/check_package_changes_all.sql
```
Schedule this as part of weekly code review process.
---
## Quick Reference
### Essential Commands
| Task | Command |
|------|---------|
| **Check current version** | `SELECT PACKAGE_NAME.GET_VERSION() FROM DUAL;` |
| **Check build info** | `SELECT PACKAGE_NAME.GET_BUILD_INFO() FROM DUAL;` |
| **Check for changes** | `SELECT ENV_MANAGER.CHECK_PACKAGE_CHANGES('OWNER', 'PACKAGE') FROM DUAL;` |
| **Get hash info** | `SELECT ENV_MANAGER.GET_PACKAGE_HASH_INFO('OWNER', 'PACKAGE') FROM DUAL;` |
| **Track version** | `CALL ENV_MANAGER.TRACK_PACKAGE_VERSION('OWNER', 'PKG', 'VER', 'DATE', 'AUTHOR');` |
| **Check errors** | `SELECT * FROM ALL_ERRORS WHERE OWNER = 'CT_MRDS' AND NAME = 'PACKAGE_NAME';` |
| **View tracking history** | `SELECT * FROM A_PACKAGE_VERSION_TRACKING WHERE PACKAGE_NAME = 'X' ORDER BY TRACKING_DATE DESC;` |
---
### Version Number Examples
| Current | Bug Fix | Feature | Breaking |
|---------|---------|---------|----------|
| 1.0.0 | 1.0.1 | 1.1.0 | 2.0.0 |
| 2.5.3 | 2.5.4 | 2.6.0 | 3.0.0 |
| 3.2.0 | 3.2.1 | 3.3.0 | 4.0.0 |
---
### Deployment Checklist
- [ ] Check current package status (`CHECK_PACKAGE_CHANGES`)
- [ ] Make code changes in local files
- [ ] Update `PACKAGE_VERSION` constant (increment appropriately)
- [ ] Update `PACKAGE_BUILD_DATE` constant (current timestamp)
- [ ] Add entry to `VERSION_HISTORY` constant
- [ ] Deploy SPEC file
- [ ] Deploy BODY file
- [ ] Check for compilation errors (`ALL_ERRORS` with OWNER filter when using ADMIN)
- [ ] Track new version (`TRACK_PACKAGE_VERSION`)
- [ ] Verify deployment (`GET_BUILD_INFO`, `CHECK_PACKAGE_CHANGES`)
- [ ] **Update source repository** - Copy updated packages to `MARS_Packages/mrds_elt-dev-database/mrds_elt-dev-database/database/`
- [ ] Update documentation (if API changed)
- [ ] Commit changes to Git
- [ ] Notify team (if breaking changes)
---
## Related Documentation
- [Package Versioning Guide](PACKAGE_VERSIONING_README.md) - Overview of versioning system
- [Package Hash Tracking Guide](PACKAGE_HASH_TRACKING_GUIDE.md) - Technical details of hash system
- [Package Hash Quick Guide](PACKAGE_HASH_QUICK_GUIDE.md) - Quick reference for hash commands
- [Developer Quick Guide](../database/DEVELOPER_QUICK_GUIDE.md) - General development guidelines
---
## Support
For questions or issues with the deployment process:
1. Check [Troubleshooting](#troubleshooting) section above
2. Review package documentation: `SELECT GET_PACKAGE_DOCUMENTATION('PACKAGE_NAME', 'SCHEMA') FROM DUAL;`
3. Check process logs: `SELECT * FROM A_PROCESS_LOG WHERE LOG_TIMESTAMP > SYSDATE - 1 ORDER BY LOG_TIMESTAMP DESC;`
4. Contact database team lead
---
**Last Updated:** 2025-10-22
**Document Version:** 1.0.0
**System Version:** ENV_MANAGER 3.1.0+