698 lines
27 KiB
Markdown
698 lines
27 KiB
Markdown
# Table Setup Guide for FILE PROCESSOR System
|
|
|
|
This document describes the process of setting up tables for the FILE PROCESSOR system using the example of `C2D_A_UC_DISSEM_METADATA_LOADS` table setup.
|
|
|
|
## Overview
|
|
|
|
The table setup process involves migrating existing tables from operational schemas (like `OU_C2D`) to the FILE PROCESSOR framework, which includes:
|
|
- Creating template tables for external table definitions
|
|
- Setting up external tables for different storage locations (INBOX, ODS, ARCHIVE)
|
|
- Exporting existing data to cloud storage
|
|
- Creating legacy backup tables
|
|
- Setting up views to maintain compatibility
|
|
|
|
## Step-by-Step Setup Process
|
|
|
|
**Recommended Approach:** Use the `ODS.FILE_MANAGER_ODS` package for creating external tables. The `FILE_MANAGER_ODS` package is a wrapper for the FILE_MANAGER package that uses `AUTHID DEFINER` instead of `AUTHID CURRENT_USER`, which means it will always create objects in the ODS schema regardless of which user executes the procedures.
|
|
|
|
**Alternative Approach:** If you prefer using the original package, you can use `CT_MRDS.FILE_MANAGER`, but the CREATE_EXTERNAL_TABLE procedure must be run as the ODS user due to the `AUTHID CURRENT_USER` clause. Export procedures (EXPORT_TABLE_DATA_TO_CSV_BY_DATE, EXPORT_TABLE_DATA_BY_DATE) have been moved to the `CT_MRDS.DATA_EXPORTER` package.
|
|
|
|
Example usage:
|
|
```sql
|
|
-- Recommended: Use DEFINER package (works from any user context)
|
|
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(...)
|
|
|
|
-- Alternative: Use CURRENT_USER package (requires ODS user context)
|
|
-- CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(...)
|
|
```
|
|
|
|
### Step 1: Create Template Table
|
|
|
|
Create a template table in the `CT_ET_TEMPLATES` schema based on the existing operational table structure:
|
|
|
|
```sql
|
|
CREATE TABLE CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS
|
|
AS SELECT * FROM OU_C2D.A_UC_DISSEM_METADATA_LOADS WHERE 1=2;
|
|
```
|
|
|
|
**Purpose:**
|
|
- The template table defines the structure for external tables
|
|
- Uses `WHERE 1=2` to copy only the structure, not the data
|
|
- Located in `CT_ET_TEMPLATES` schema for centralized template management
|
|
|
|
### Step 2: Configure FILE_MANAGER System
|
|
|
|
Before creating external tables, configure the FILE_MANAGER system with source information and file processing rules, as the `CREATE_EXTERNAL_TABLE` procedure uses data from configuration tables. For detailed information on configuring the FILE_MANAGER package procedures including:
|
|
|
|
- **ADD_SOURCE**: Registering new source systems
|
|
- **ADD_SOURCE_FILE_CONFIG**: Configuring file processing rules and naming patterns (**MARS-1049**: now includes `pEncoding` parameter for CSV character set support)
|
|
- **ADD_COLUMN_DATE_FORMAT**: Setting up date format handling for specific columns
|
|
|
|
See the comprehensive [FILE_MANAGER Configuration Guide](FILE_MANAGER_Configuration_Guide.md).
|
|
|
|
**MARS-1049 Enhancement Note**: The `ADD_SOURCE_FILE_CONFIG` procedure now supports the `pEncoding` parameter to specify character encodings (e.g., UTF8, WE8MSWIN1252) for proper international character handling in CSV files.
|
|
|
|
This configuration enables automatic file processing workflows where files uploaded to the INBOX are automatically processed and moved to ODS, with historical data archived in partitioned PARQUET format.
|
|
|
|
### Step 3: Create External Tables
|
|
|
|
Create external tables for different storage locations using the `FILE_MANAGER.CREATE_EXTERNAL_TABLE` procedure:
|
|
|
|
```sql
|
|
-- External table for INBOX (incoming files)
|
|
BEGIN
|
|
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
|
pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_INBOX',
|
|
pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
pPrefix => 'INBOX/C2D/UC_DISSEM/A_UC_DISSEM_METADATA_LOADS',
|
|
pBucketUri => CT_MRDS.ENV_MANAGER.gvInboxBucketUri
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Alternative using CURRENT_USER package (requires ODS user context)
|
|
-- BEGIN
|
|
-- CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
|
-- pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_INBOX',
|
|
-- pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
-- pPrefix => 'INBOX/C2D/UC_DISSEM/A_UC_DISSEM_METADATA_LOADS',
|
|
-- pBucketUri => CT_MRDS.ENV_MANAGER.gvInboxBucketUri
|
|
-- );
|
|
-- END;
|
|
-- /
|
|
|
|
-- External table for ODS (operational data store)
|
|
BEGIN
|
|
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
|
pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_ODS',
|
|
pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
pPrefix => 'ODS/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Alternative using CURRENT_USER package (requires ODS user context)
|
|
-- BEGIN
|
|
-- CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
|
-- pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_ODS',
|
|
-- pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
-- pPrefix => 'ODS/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
-- pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
|
|
-- );
|
|
-- END;
|
|
-- /
|
|
|
|
-- External table for ARCHIVE (historical data)
|
|
BEGIN
|
|
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
|
pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_ARCHIVE',
|
|
pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
pPrefix => 'ARCHIVE/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Alternative using CURRENT_USER package (requires ODS user context)
|
|
-- BEGIN
|
|
-- CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
|
-- pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_ARCHIVE',
|
|
-- pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
-- pPrefix => 'ARCHIVE/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
-- pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
|
-- );
|
|
-- END;
|
|
-- /
|
|
```
|
|
|
|
**Parameters:**
|
|
- `pTableName`: Name of the external table to create
|
|
- `pTemplateTableName`: Template table defining the structure
|
|
- `pPrefix`: Storage path prefix in Oracle Cloud Storage
|
|
- `pBucketUri`: URI of the target bucket (uses ENV_MANAGER global variables for different storage types)
|
|
|
|
**Storage Locations:**
|
|
- **INBOX**: For incoming files awaiting processing (uses `gvInboxBucketUri`)
|
|
- **ODS**: For processed files in operational data store (uses `gvDataBucketUri`)
|
|
- **ARCHIVE**: For historical/archived files (uses `gvArchiveBucketUri`)
|
|
|
|
### Step 4: Export Data to ODS Bucket (CSV Format)
|
|
|
|
Export existing operational data to ODS bucket in CSV format using the `DATA_EXPORTER` package:
|
|
|
|
```sql
|
|
-- Export all data to CSV format (using default pMinDate = 1900-01-01 and pMaxDate = SYSDATE)
|
|
BEGIN
|
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
|
pSchemaName => 'OU_C2D', -- Source schema
|
|
pTableName => 'A_UC_DISSEM_METADATA_LOADS', -- Source table
|
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK', -- Key column for partitioning
|
|
pBucketName => 'mrds_data_poc', -- Target bucket (ODS)
|
|
pFolderName => 'ODS/C2D/A_UC_DISSEM_METADATA_LOADS' -- Target folder
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Export data within a specific date range to CSV
|
|
BEGIN
|
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
|
pSchemaName => 'OU_C2D',
|
|
pTableName => 'A_UC_DISSEM_METADATA_LOADS',
|
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
|
pBucketName => 'mrds_data_poc',
|
|
pFolderName => 'ODS/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
pMinDate => DATE '2024-01-01', -- Export data from 2024-01-01
|
|
pMaxDate => DATE '2024-12-31' -- Export data up to 2024-12-31
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Export only recent data to CSV (last 30 days)
|
|
BEGIN
|
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
|
pSchemaName => 'OU_C2D',
|
|
pTableName => 'A_UC_DISSEM_METADATA_LOADS',
|
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
|
pBucketName => 'mrds_data_poc',
|
|
pFolderName => 'ODS/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
pMinDate => SYSDATE - 30 -- Export data from last 30 days
|
|
);
|
|
END;
|
|
/
|
|
```
|
|
|
|
**Purpose:**
|
|
- Exports existing data to ODS bucket in CSV format for immediate operational use
|
|
- Creates CSV files partitioned by date (YYYYMM format)
|
|
- Files are ready for consumption by external tables and processing workflows
|
|
- Uses `mrds_data_poc` bucket which corresponds to `gvDataBucketUri`
|
|
|
|
### Step 5: Export Historical Data to Archive Bucket (PARQUET Format)
|
|
|
|
Export existing operational data to cloud storage using partitioning by date with the `DATA_EXPORTER` package:
|
|
|
|
```sql
|
|
-- Export all data (using default pMinDate = 1900-01-01 and pMaxDate = SYSDATE)
|
|
BEGIN
|
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
|
pSchemaName => 'OU_C2D', -- Source schema
|
|
pTableName => 'A_UC_DISSEM_METADATA_LOADS', -- Source table
|
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK', -- Key column for partitioning
|
|
pBucketName => 'mrds_history_poc', -- Target bucket
|
|
pFolderName => 'C2D/A_UC_DISSEM_METADATA_LOADS' -- Target folder
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Export data within a specific date range
|
|
BEGIN
|
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
|
pSchemaName => 'OU_C2D',
|
|
pTableName => 'A_UC_DISSEM_METADATA_LOADS',
|
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
|
pBucketName => 'mrds_history_poc',
|
|
pFolderName => 'C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
pMinDate => DATE '2024-01-01', -- Export data from 2024-01-01
|
|
pMaxDate => DATE '2024-12-31' -- Export data up to 2024-12-31
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Export only recent data (last 30 days)
|
|
BEGIN
|
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
|
pSchemaName => 'OU_C2D',
|
|
pTableName => 'A_UC_DISSEM_METADATA_LOADS',
|
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
|
pBucketName => 'mrds_history_poc',
|
|
pFolderName => 'C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
pMinDate => SYSDATE - 30 -- Export data from last 30 days
|
|
);
|
|
END;
|
|
/
|
|
```
|
|
|
|
**Purpose:**
|
|
- Exports existing data to cloud storage before switching to FILE_MANAGER
|
|
- Creates PARQUET files partitioned by date (YEAR_MONTH)
|
|
- Ensures data preservation during migration
|
|
|
|
### Step 6: Create Legacy Backup Table
|
|
|
|
Rename the original table to preserve existing data:
|
|
|
|
```sql
|
|
ALTER TABLE OU_C2D.A_UC_DISSEM_METADATA_LOADS
|
|
RENAME TO A_UC_DISSEM_METADATA_LOADS_LEGACY;
|
|
```
|
|
|
|
**Purpose:**
|
|
- Preserves original table as backup
|
|
- Allows rollback if needed
|
|
- Maintains data integrity during migration
|
|
|
|
### Step 7: Create Compatibility View
|
|
|
|
Create a view that points to the new ODS external table:
|
|
|
|
```sql
|
|
-- Grant access to the ODS external table
|
|
GRANT SELECT ON ods.C2D_A_UC_DISSEM_METADATA_LOADS_ODS TO OU_C2D;
|
|
|
|
-- Create view with original table name
|
|
CREATE OR REPLACE VIEW OU_C2D.A_UC_DISSEM_METADATA_LOADS AS
|
|
SELECT * FROM ods.C2D_A_UC_DISSEM_METADATA_LOADS_ODS;
|
|
```
|
|
|
|
**Purpose:**
|
|
- Maintains compatibility with existing applications
|
|
- Redirects queries to FILE PROCESSOR external tables
|
|
- Seamless transition for dependent systems
|
|
|
|
## Package Procedures Used
|
|
|
|
### FILE_MANAGER Package (External Tables)
|
|
**Recommended Approach:** Use the **ODS.FILE_MANAGER_ODS** package which uses `AUTHID DEFINER` and will create objects in the ODS schema regardless of the executing user. This is the most reliable approach for creating external tables.
|
|
|
|
**Alternative Approach:** You can use the `CT_MRDS.FILE_MANAGER` package, but the `CREATE_EXTERNAL_TABLE` procedure must be executed as the **ODS user** due to the `AUTHID CURRENT_USER` clause.
|
|
|
|
### DATA_EXPORTER Package (Data Export)
|
|
Data export procedures have been moved to the `CT_MRDS.DATA_EXPORTER` package, which provides enhanced functionality and better separation of concerns.
|
|
|
|
### CREATE_EXTERNAL_TABLE
|
|
|
|
Creates external tables that can read data from Oracle Cloud Storage.
|
|
|
|
**Signature:**
|
|
```sql
|
|
PROCEDURE CREATE_EXTERNAL_TABLE (
|
|
pTableName IN VARCHAR2,
|
|
pTemplateTableName IN VARCHAR2,
|
|
pPrefix IN VARCHAR2,
|
|
pBucketUri IN VARCHAR2 DEFAULT ENV_MANAGER.gvInboxBucketUri,
|
|
pFileName IN VARCHAR2 DEFAULT NULL,
|
|
pDelimiter IN VARCHAR2 DEFAULT ','
|
|
);
|
|
```
|
|
|
|
### DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE
|
|
|
|
Exports table data to cloud storage in CSV format with date-based partitioning.
|
|
|
|
**Signature:**
|
|
```sql
|
|
PROCEDURE EXPORT_TABLE_DATA_TO_CSV_BY_DATE (
|
|
pSchemaName IN VARCHAR2,
|
|
pTableName IN VARCHAR2,
|
|
pKeyColumnName IN VARCHAR2,
|
|
pBucketArea IN VARCHAR2, -- Updated: now uses pBucketArea instead of pBucketName
|
|
pFolderName IN VARCHAR2,
|
|
pFileName IN VARCHAR2 DEFAULT NULL,
|
|
pColumnList IN VARCHAR2 DEFAULT NULL, -- New: allows specifying custom columns
|
|
pMinDate IN DATE DEFAULT DATE '1900-01-01',
|
|
pMaxDate IN DATE DEFAULT SYSDATE,
|
|
pCredentialName IN VARCHAR2 DEFAULT ENV_MANAGER.gvCredentialName
|
|
);
|
|
```
|
|
|
|
**Parameters:**
|
|
- `pSchemaName`: Schema containing the source table
|
|
- `pTableName`: Name of the table to export
|
|
- `pKeyColumnName`: Column name used for date-based filtering (typically LOAD_START or similar date column)
|
|
- `pBucketName`: Oracle Cloud Storage bucket name for export
|
|
- `pFolderName`: Folder path within the bucket
|
|
- `pFileName`: Custom filename prefix (optional). If NULL, uses table name as prefix
|
|
- `pMinDate`: Minimum date for filtering records (defaults to DATE '1900-01-01'). Only records where the key column is >= pMinDate will be exported
|
|
- `pMaxDate`: Maximum date for filtering records (defaults to SYSDATE). Only records where the key column is <= pMaxDate will be exported
|
|
- `pNamespace`: OCI namespace (defaults to environment configuration)
|
|
- `pRegion`: OCI region (defaults to environment configuration)
|
|
- `pCredentialName`: OCI credentials (defaults to environment configuration)
|
|
|
|
**Purpose:**
|
|
- Creates separate CSV files partitioned by year and month (YYYYMM format)
|
|
- Files are immediately ready for consumption by external tables
|
|
- Ideal for operational data that needs to be processed quickly
|
|
- File naming pattern: `{pFileName}_YYYYMM.csv` or `{TABLE_NAME}_YYYYMM.csv` (if pFileName is NULL)
|
|
|
|
### DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE
|
|
|
|
Exports table data to cloud storage in PARQUET format with date-based partitioning.
|
|
|
|
**Signature:**
|
|
```sql
|
|
PROCEDURE EXPORT_TABLE_DATA_BY_DATE (
|
|
pSchemaName IN VARCHAR2,
|
|
pTableName IN VARCHAR2,
|
|
pKeyColumnName IN VARCHAR2,
|
|
pBucketArea IN VARCHAR2, -- Updated: now uses pBucketArea instead of pBucketName
|
|
pFolderName IN VARCHAR2,
|
|
pColumnList IN VARCHAR2 DEFAULT NULL, -- New: allows specifying custom columns
|
|
pMinDate IN DATE DEFAULT DATE '1900-01-01',
|
|
pMaxDate IN DATE DEFAULT SYSDATE,
|
|
pCredentialName IN VARCHAR2 DEFAULT ENV_MANAGER.gvCredentialName
|
|
);
|
|
```
|
|
|
|
**Parameters:**
|
|
- `pSchemaName`: Schema containing the source table
|
|
- `pTableName`: Name of the table to export
|
|
- `pKeyColumnName`: Column name used for date-based filtering (typically LOAD_START or similar date column)
|
|
- `pBucketArea`: Bucket area identifier ('INBOX', 'ODS', 'DATA', 'ARCHIVE') - automatically maps to correct bucket URI
|
|
- `pFolderName`: Folder path within the bucket
|
|
- `pColumnList`: Optional comma-separated list of columns to export (uses T.* if NULL)
|
|
- `pMinDate`: Minimum date for filtering records (defaults to DATE '1900-01-01'). Only records where the key column is >= pMinDate will be exported
|
|
- `pMaxDate`: Maximum date for filtering records (defaults to SYSDATE). Only records where the key column is <= pMaxDate will be exported
|
|
- `pCredentialName`: OCI credentials (defaults to environment configuration)
|
|
|
|
## Best Practices
|
|
|
|
### 1. Naming Conventions
|
|
|
|
- **Template tables**: `CT_ET_TEMPLATES.{SOURCE}_{TABLE_NAME}`
|
|
- **External tables**: `{SOURCE}_{TABLE_NAME}_{LOCATION}` (e.g., `_INBOX`, `_ODS`, `_ARCHIVE`)
|
|
- **Legacy tables**: `{ORIGINAL_NAME}_LEGACY`
|
|
|
|
### 2. Schema Organization
|
|
|
|
- **CT_ET_TEMPLATES**: Template table definitions
|
|
- **ODS**: External tables for processed data
|
|
- **OU_{SOURCE}**: Compatibility views and legacy tables
|
|
|
|
### 3. Storage Structure
|
|
|
|
```
|
|
Oracle Cloud Storage Buckets Structure:
|
|
|
|
INBOX Bucket:
|
|
├── INBOX/
|
|
│ └── {SOURCE}/
|
|
│ └── {SOURCE_FILE_ID}/
|
|
│ └── {TABLE_NAME}/
|
|
|
|
DATA Bucket:
|
|
├── ODS/
|
|
│ └── {SOURCE}/
|
|
│ └── {TABLE_NAME}/
|
|
└── TRASH/ -- File retention subfolder (not a separate bucket)
|
|
└── {SOURCE}/
|
|
└── {TABLE_NAME}/ -- CSV files after archival (ARCHIVED_AND_TRASHED status)
|
|
|
|
ARCHIVE Bucket:
|
|
└── ARCHIVE/
|
|
└── {SOURCE}/
|
|
└── {TABLE_NAME}/
|
|
└── PARTITION_YEAR=*/
|
|
└── PARTITION_MONTH=*/
|
|
└── *.parquet
|
|
|
|
Note: TRASH is a subfolder within the DATA bucket for file retention and rollback capability.
|
|
```
|
|
|
|
### 4. Migration Checklist
|
|
|
|
- [ ] Create template table
|
|
- [ ] Configure FILE_MANAGER system (ADD_SOURCE, ADD_SOURCE_FILE_CONFIG, ADD_COLUMN_DATE_FORMAT)
|
|
- [ ] Create external tables (INBOX, ODS, ARCHIVE)
|
|
- [ ] Export data to ODS bucket (CSV format) (optional) (data baudries)
|
|
- [ ] Export historical data to archive bucket (PARQUET format)
|
|
- [ ] Rename original table to legacy
|
|
- [ ] Create compatibility view
|
|
- [ ] Test data access through view
|
|
- [ ] Verify error handling
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Execution Context Issues**
|
|
- **Problem:** External tables created in wrong schema
|
|
- **Solution 1 (Recommended):** Use the DEFINER package that works from any user context
|
|
```sql
|
|
-- Use ODS.FILE_MANAGER_ODS instead of CT_MRDS.FILE_MANAGER
|
|
BEGIN
|
|
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(...);
|
|
END;
|
|
/
|
|
```
|
|
- **Solution 2 (Alternative):** Ensure CREATE_EXTERNAL_TABLE procedure is executed as ODS user
|
|
```sql
|
|
-- Check current user context
|
|
SELECT USER FROM DUAL;
|
|
-- Should return: ODS
|
|
```
|
|
|
|
2. **Permission Errors**
|
|
```sql
|
|
-- Grant necessary permissions
|
|
GRANT SELECT ON CT_ET_TEMPLATES.{TEMPLATE_TABLE} TO CT_MRDS;
|
|
GRANT SELECT ON ods.{EXTERNAL_TABLE} TO {TARGET_SCHEMA};
|
|
```
|
|
|
|
3. **External Table Creation Failures**
|
|
- Verify bucket and folder paths exist
|
|
- Check credential configuration
|
|
- Ensure template table structure is correct
|
|
|
|
4. **Data Export Issues**
|
|
- Verify source table has data
|
|
- Check key column exists and has appropriate data type
|
|
- Ensure sufficient storage space in target bucket
|
|
|
|
5. **File Validation Failures (ORA-20011)**
|
|
- **Problem:** CSV file contains more columns than template table allows
|
|
- **Error Message:** "EXCESS COLUMNS DETECTED! CSV file has X columns but template expects only Y"
|
|
- **Solutions:**
|
|
- Remove excess columns from CSV file before processing
|
|
- Add missing columns to template table
|
|
- Use `ANALYZE_VALIDATION_ERRORS()` function for detailed analysis
|
|
- **Prevention:** Ensure CSV structure matches template table before upload
|
|
|
|
6. **External Table Query Failures (ORA-29913/KUP-05002)**
|
|
- **Problem:** "ORA-29913: error while processing ODCIEXTTABLEOPEN routine" with "KUP-05002: There are no matching files for any file specification in the LOCATION clause"
|
|
- **Cause:** Oracle cannot find files in the specified external table location
|
|
- **Common Scenarios:**
|
|
- Empty bucket/folder - no files uploaded yet
|
|
- Incorrect file path in LOCATION clause
|
|
- Wrong file name pattern (e.g., looking for *.csv but files are *.txt)
|
|
- Case sensitivity issues in file names
|
|
- **Solutions:**
|
|
```sql
|
|
-- 1. Check external table location
|
|
SELECT table_name, location
|
|
FROM user_external_locations
|
|
WHERE table_name = 'YOUR_EXTERNAL_TABLE';
|
|
|
|
-- 2. List files in bucket to verify they exist
|
|
SELECT object_name FROM DBMS_CLOUD.LIST_OBJECTS(
|
|
credential_name => 'YOUR_CREDENTIAL',
|
|
location_uri => 'YOUR_BUCKET_URI',
|
|
prefix => 'YOUR_FOLDER_PREFIX'
|
|
);
|
|
|
|
-- 3. Test with a simple file upload
|
|
-- Upload a test CSV file to the exact location specified in external table
|
|
```
|
|
- **Prevention:** Always verify file location matches external table LOCATION clause exactly
|
|
|
|
### Verification Queries
|
|
|
|
```sql
|
|
-- Check template table structure
|
|
SELECT column_name, data_type, data_length
|
|
FROM user_tab_columns
|
|
WHERE table_name = '{TEMPLATE_TABLE_NAME}'
|
|
ORDER BY column_id;
|
|
|
|
-- Verify external table creation
|
|
SELECT table_name, table_type
|
|
FROM user_tables
|
|
WHERE table_name LIKE '%{SOURCE}%{TABLE}%';
|
|
|
|
-- Test view access
|
|
SELECT COUNT(*) FROM OU_{SOURCE}.{TABLE_NAME};
|
|
|
|
-- Check exported files
|
|
SELECT object_name
|
|
FROM dbms_cloud.list_objects('{BUCKET_NAME}', '{FOLDER_PREFIX}');
|
|
```
|
|
|
|
## Example: Complete Setup Script
|
|
|
|
Here's a complete example based on the C2D UC_DISSEM metadata loads table:
|
|
|
|
```sql
|
|
-- Step 1: Create template table
|
|
CREATE TABLE CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS
|
|
AS SELECT * FROM OU_C2D.A_UC_DISSEM_METADATA_LOADS WHERE 1=2;
|
|
|
|
-- Step 2: Configure FILE_MANAGER system
|
|
CALL CT_MRDS.FILE_MANAGER.ADD_SOURCE(
|
|
pSourceKey => 'C2D',
|
|
pSourceName => 'Central Bank Data System'
|
|
);
|
|
|
|
CALL CT_MRDS.FILE_MANAGER.ADD_SOURCE_FILE_CONFIG(
|
|
pSourceKey => 'C2D',
|
|
pSourceFileType => 'INPUT',
|
|
pSourceFileId => 'UC_DISSEM',
|
|
pSourceFileDesc => 'UC Dissemination Metadata Loads',
|
|
pSourceFileNamePattern => 'UC_NMA_DISSEM-*.csv',
|
|
pTableId => 'A_UC_DISSEM_METADATA_LOADS',
|
|
pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
pContainerFileKey => NULL
|
|
);
|
|
|
|
CALL CT_MRDS.FILE_MANAGER.ADD_COLUMN_DATE_FORMAT(
|
|
pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
pColumnName => 'A_ETL_LOAD_SET_FK',
|
|
pDateFormat => 'YYYY-MM-DD'
|
|
);
|
|
|
|
-- Step 3: Create external tables
|
|
BEGIN
|
|
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
|
pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_INBOX',
|
|
pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
pPrefix => 'INBOX/C2D/UC_DISSEM/A_UC_DISSEM_METADATA_LOADS',
|
|
pBucketUri => CT_MRDS.ENV_MANAGER.gvInboxBucketUri
|
|
);
|
|
END;
|
|
/
|
|
|
|
BEGIN
|
|
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
|
pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_ODS',
|
|
pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
pPrefix => 'ODS/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
|
|
);
|
|
END;
|
|
/
|
|
|
|
BEGIN
|
|
ODS.FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
|
|
pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_ARCHIVE',
|
|
pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
pPrefix => 'ARCHIVE/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Alternative using CURRENT_USER package (requires connection as ODS user):
|
|
-- BEGIN
|
|
-- CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
|
-- pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_INBOX',
|
|
-- pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
-- pPrefix => 'INBOX/C2D/UC_DISSEM/A_UC_DISSEM_METADATA_LOADS',
|
|
-- pBucketUri => CT_MRDS.ENV_MANAGER.gvInboxBucketUri
|
|
-- );
|
|
-- END;
|
|
-- /
|
|
-- BEGIN
|
|
-- CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
|
-- pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_ODS',
|
|
-- pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
-- pPrefix => 'ODS/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
-- pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
|
|
-- );
|
|
-- END;
|
|
-- /
|
|
-- BEGIN
|
|
-- CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
|
|
-- pTableName => 'C2D_A_UC_DISSEM_METADATA_LOADS_ARCHIVE',
|
|
-- pTemplateTableName => 'CT_ET_TEMPLATES.C2D_A_UC_DISSEM_METADATA_LOADS',
|
|
-- pPrefix => 'ARCHIVE/C2D/A_UC_DISSEM_METADATA_LOADS',
|
|
-- pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
|
|
-- );
|
|
-- END;
|
|
-- /
|
|
|
|
-- Step 4: Export data to ODS bucket (CSV format)
|
|
BEGIN
|
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_TO_CSV_BY_DATE(
|
|
pSchemaName => 'OU_C2D',
|
|
pTableName => 'A_UC_DISSEM_METADATA_LOADS',
|
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
|
pBucketArea => 'ODS', -- Updated: uses bucket area instead of bucket name
|
|
pFolderName => 'C2D/UC_DISSEM/A_UC_DISSEM_METADATA_LOADS'
|
|
-- pMinDate defaults to DATE '1900-01-01' (exports all historical data)
|
|
-- pMaxDate defaults to SYSDATE (exports all data up to current date)
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Step 5: Export historical data to archive bucket (PARQUET format)
|
|
BEGIN
|
|
CT_MRDS.DATA_EXPORTER.EXPORT_TABLE_DATA_BY_DATE(
|
|
pSchemaName => 'OU_C2D',
|
|
pTableName => 'A_UC_DISSEM_METADATA_LOADS',
|
|
pKeyColumnName => 'A_ETL_LOAD_SET_FK',
|
|
pBucketArea => 'ARCHIVE', -- Updated: uses bucket area instead of bucket name
|
|
pFolderName => 'C2D/A_UC_DISSEM_METADATA_LOADS'
|
|
-- pMinDate defaults to DATE '1900-01-01' (exports all historical data)
|
|
-- pMaxDate defaults to SYSDATE (exports all data up to current date)
|
|
);
|
|
END;
|
|
/
|
|
|
|
-- Step 6: Create legacy backup
|
|
ALTER TABLE OU_C2D.A_UC_DISSEM_METADATA_LOADS RENAME TO A_UC_DISSEM_METADATA_LOADS_LEGACY;
|
|
|
|
-- Step 7: Create compatibility view
|
|
GRANT SELECT ON ods.C2D_A_UC_DISSEM_METADATA_LOADS_ODS TO OU_C2D;
|
|
CREATE OR REPLACE VIEW OU_C2D.A_UC_DISSEM_METADATA_LOADS AS
|
|
SELECT * FROM ods.C2D_A_UC_DISSEM_METADATA_LOADS_ODS;
|
|
|
|
-- Verify setup
|
|
SHOW ERRORS;
|
|
SELECT COUNT(*) FROM OU_C2D.A_UC_DISSEM_METADATA_LOADS;
|
|
```
|
|
|
|
## ENV_MANAGER Global Variables
|
|
|
|
The system uses `ENV_MANAGER` package global variables to manage different bucket URIs:
|
|
|
|
- `gvInboxBucketUri`: URI for incoming files bucket
|
|
- `gvDataBucketUri`: URI for operational data store bucket
|
|
- `gvArchiveBucketUri`: URI for historical/archive data bucket
|
|
|
|
This ensures consistent bucket configuration across all external table creation calls.
|
|
|
|
### Checking ENV_MANAGER Variable Values
|
|
|
|
To verify the current values of ENV_MANAGER global variables, use this script:
|
|
|
|
```sql
|
|
SET SERVEROUTPUT ON;
|
|
DECLARE
|
|
v_value1 VARCHAR2(4000);
|
|
v_value2 VARCHAR2(4000);
|
|
v_value3 VARCHAR2(4000);
|
|
BEGIN
|
|
v_value1 := CT_MRDS.ENV_MANAGER.gvInboxBucketUri;
|
|
v_value2 := CT_MRDS.ENV_MANAGER.gvDataBucketUri;
|
|
v_value3 := CT_MRDS.ENV_MANAGER.gvArchiveBucketUri;
|
|
DBMS_OUTPUT.PUT_LINE('------>>>> gvInboxBucketUri: ' || v_value1);
|
|
DBMS_OUTPUT.PUT_LINE('------>>>> gvDataBucketUri: ' || v_value2);
|
|
DBMS_OUTPUT.PUT_LINE('------>>>> gvArchiveBucketUri: ' || v_value3);
|
|
END;
|
|
/
|
|
```
|
|
|
|
This script helps troubleshoot external table creation issues by verifying that bucket URIs are properly configured.
|
|
|
|
## Summary
|
|
|
|
This process successfully migrates traditional Oracle tables to the FILE PROCESSOR framework, enabling cloud-based file processing while maintaining application compatibility. The migration includes:
|
|
|
|
1. **Template Creation** - Defining table structures in CT_ET_TEMPLATES schema
|
|
2. **FILE_MANAGER Configuration** - Setting up source systems, file processing rules, and date formats
|
|
3. **External Tables Setup** - Creating INBOX, ODS, and ARCHIVE external tables
|
|
4. **Data Export (CSV)** - Moving existing data to ODS bucket in CSV format for immediate processing
|
|
5. **Data Export (PARQUET)** - Moving historical data to archive bucket in PARQUET format for long-term storage
|
|
6. **Legacy Preservation** - Backing up original tables and creating compatibility views
|
|
|
|
After completion, your system will be ready for automated file processing with cloud-based storage and external table access patterns.
|