#Requires -Version 5.1 <# .SYNOPSIS Import CONTAFIN_ORACLE schema from Data Pump dump file. .DESCRIPTION Imports the CONTAFIN_ORACLE schema using Oracle Data Pump (impdp). - Creates DMPDIR directory if not exists - Runs impdp with optimal parameters - Verifies import (object count, invalid objects) .PARAMETER DumpFile Path to the CONTAFIN_ORACLE DMP file. If not specified, auto-detects from DmpDir. .PARAMETER OracleHome Oracle home directory. If not specified, auto-detects. .PARAMETER ServiceName Database service name. Default: XEPDB1 .PARAMETER SystemPassword SYSTEM user password. Default: romfastsoft .PARAMETER DmpDir Oracle directory path for Data Pump. Default: C:\DMPDIR .PARAMETER TableExistsAction What to do if table exists: SKIP, APPEND, TRUNCATE, REPLACE. Default: REPLACE .PARAMETER Parallel Number of parallel workers for import. Default: 2 .EXAMPLE .\03-import-contafin.ps1 -DumpFile "C:\dumps\CONTAFIN_ORACLE.dmp" .EXAMPLE .\03-import-contafin.ps1 -DumpFile "D:\backups\contafin.dmp" -ServiceName "ROA" -SystemPassword "mypass" .NOTES File Name : 03-import-contafin.ps1 Prerequisite : Run 01-setup-database.ps1 and 02-create-sys-objects.ps1 first Copyright 2024 : ROMFAST #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$DumpFile, [Parameter(Mandatory = $false)] [string]$OracleHome, [Parameter(Mandatory = $false)] [string]$ServiceName = "XEPDB1", [Parameter(Mandatory = $false)] [string]$SystemPassword = "romfastsoft", [Parameter(Mandatory = $false)] [string]$DmpDir = "C:\DMPDIR", [Parameter(Mandatory = $false)] [ValidateSet('SKIP', 'APPEND', 'TRUNCATE', 'REPLACE')] [string]$TableExistsAction = "REPLACE", [Parameter(Mandatory = $false)] [int]$Parallel = 1 ) $ErrorActionPreference = 'Stop' # Source library functions . "$PSScriptRoot\lib\logging-functions.ps1" . "$PSScriptRoot\lib\oracle-functions.ps1" # Initialize logging $logPath = Join-Path $PSScriptRoot "..\logs\03-import-contafin_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" Initialize-LogFile -LogPath $logPath -ScriptName "03-import-contafin.ps1" # Auto-detect DumpFile if not specified if (-not $DumpFile) { Write-Host "[INFO] DumpFile not specified, searching in $DmpDir..." -ForegroundColor Yellow $candidates = Get-ChildItem -Path $DmpDir -Filter "*contafin*.dmp" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending if ($candidates) { $DumpFile = $candidates[0].FullName Write-Host "[INFO] Auto-detected DumpFile: $DumpFile" -ForegroundColor Green } else { throw "No CONTAFIN_ORACLE dump file found in $DmpDir. Please specify -DumpFile parameter or copy *contafin*.dmp to $DmpDir" } } # Validate DumpFile exists if (-not (Test-Path $DumpFile)) { throw "DumpFile not found: $DumpFile" } try { Write-LogSection "Importing CONTAFIN_ORACLE Schema" # Validate Oracle installation $oraHome = Get-OracleHome -OracleHome $OracleHome Write-LogSuccess "Oracle Home: $oraHome" # Test connection Write-Log "Testing database connection..." if (-not (Test-OracleConnection -OracleHome $oraHome -ServiceName $ServiceName ` -Password $SystemPassword)) { throw "Cannot connect to database. Please verify ServiceName and SystemPassword." } Write-LogSuccess "Database connection successful" # Verify CONTAFIN_ORACLE user exists Write-Log "Verifying CONTAFIN_ORACLE user exists..." if (-not (Test-OracleUser -OracleHome $oraHome -ServiceName $ServiceName ` -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE")) { throw "User CONTAFIN_ORACLE does not exist. Run 01-setup-database.ps1 first." } Write-LogSuccess "User CONTAFIN_ORACLE exists" # Create/verify DMPDIR Write-LogSection "Configuring Data Pump Directory" if (-not (Test-Path -Path $DmpDir)) { New-Item -ItemType Directory -Path $DmpDir -Force | Out-Null Write-Log "Created directory: $DmpDir" } New-OracleDirectory -OracleHome $oraHome -ServiceName $ServiceName ` -Password $SystemPassword -DirectoryName "DMPDIR" -DirectoryPath $DmpDir # Copy dump file to DMPDIR if not already there $dumpFileName = Split-Path -Path $DumpFile -Leaf $targetDumpPath = Join-Path $DmpDir $dumpFileName # Resolve paths for accurate comparison (handles casing and path format differences) $resolvedSource = (Resolve-Path -Path $DumpFile -ErrorAction SilentlyContinue).Path $resolvedTarget = if (Test-Path $targetDumpPath) { (Resolve-Path -Path $targetDumpPath).Path } else { $null } if ($resolvedSource -ne $resolvedTarget) { Write-Log "Copying dump file to DMPDIR..." Copy-Item -Path $DumpFile -Destination $targetDumpPath -Force Write-LogSuccess "Dump file copied to: $targetDumpPath" } else { Write-Log "Dump file already in DMPDIR: $targetDumpPath" } # Check dump file size $dumpFileInfo = Get-Item $targetDumpPath $dumpSizeMB = [math]::Round($dumpFileInfo.Length / 1MB, 2) Write-Log "Dump file size: $dumpSizeMB MB" # Get current object count before import Write-Log "Getting current object count for CONTAFIN_ORACLE..." $beforeCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE" $beforeTotal = if ($beforeCounts['TOTAL']) { $beforeCounts['TOTAL'] } else { 0 } Write-Log "Objects before import: $beforeTotal" # Run import Write-LogSection "Running Data Pump Import" $impdpPath = Join-Path $oraHome "bin\impdp.exe" if (-not (Test-Path -Path $impdpPath)) { throw "impdp.exe not found at: $impdpPath" } $importLogFile = "CONTAFIN_ORACLE_import_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" # Get listener host for connection (handles listener bound to specific IP) $dbHost = Get-ListenerHost -OracleHome $oraHome $dbPort = 1521 # Build impdp command with EZConnect format $connString = "SYSTEM/`"$SystemPassword`"@${dbHost}:${dbPort}/${ServiceName}" $impdpParams = @( "`"$connString`"", "directory=DMPDIR", "dumpfile=$dumpFileName", "logfile=$importLogFile", "schemas=CONTAFIN_ORACLE", "table_exists_action=$TableExistsAction", "parallel=$Parallel" # Always specify to override DMP metadata (XE requires parallel=1) ) $arguments = $impdpParams -join " " Write-Log "Executing impdp..." Write-Log "Parameters: directory=DMPDIR dumpfile=$dumpFileName schemas=CONTAFIN_ORACLE table_exists_action=$TableExistsAction" # Set Oracle environment $env:ORACLE_HOME = $oraHome $env:PATH = "$oraHome\bin;$env:PATH" $env:NLS_LANG = "AMERICAN_AMERICA.AL32UTF8" $startTime = Get-Date # Execute impdp $process = Start-Process -FilePath $impdpPath -ArgumentList $arguments -Wait -NoNewWindow -PassThru $duration = (Get-Date) - $startTime Write-Log "Import completed in $([math]::Round($duration.TotalMinutes, 2)) minutes" # Check import log $importLogPath = Join-Path $DmpDir $importLogFile if (Test-Path -Path $importLogPath) { Write-Log "Import log: $importLogPath" # Read and analyze log for errors $logContent = Get-Content -Path $importLogPath -Raw if ($logContent -match "ORA-\d{5}:") { Write-LogWarning "Import completed with Oracle errors. Check log for details." } if ($logContent -match "successfully loaded/unloaded") { Write-LogSuccess "Objects successfully loaded" } # Count errors and warnings in log $errorCount = ([regex]::Matches($logContent, "ORA-\d{5}:")).Count $warningCount = ([regex]::Matches($logContent, "ORA-39\d{3}:")).Count Write-Log "Errors in log: $errorCount" Write-Log "Warnings in log: $warningCount" } # Verify import Write-LogSection "Verifying Import" # Get object counts after import $afterCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE" $afterTotal = if ($afterCounts['TOTAL']) { $afterCounts['TOTAL'] } else { 0 } $afterInvalid = if ($afterCounts['INVALID']) { $afterCounts['INVALID'] } else { 0 } Write-Log "Objects after import: $afterTotal" Write-Log "Objects imported: $($afterTotal - $beforeTotal)" # Display object counts by type Write-Log "" Write-Log "Object counts by type:" foreach ($key in $afterCounts.Keys | Sort-Object) { if ($key -ne 'TOTAL' -and $key -ne 'INVALID') { Write-Log " $($key): $($afterCounts[$key])" } } if ($afterInvalid -gt 0) { Write-LogWarning "Invalid objects: $afterInvalid" # List invalid objects $invalidSql = @" SET PAGESIZE 100 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF LINESIZE 200 SELECT object_name, object_type FROM dba_objects WHERE owner = 'CONTAFIN_ORACLE' AND status = 'INVALID' ORDER BY object_type, object_name; EXIT; "@ $invalidList = Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` -Username "SYSTEM" -Password $SystemPassword -SqlCommand $invalidSql -Silent Write-Log "Invalid objects:" Write-Host $invalidList # Attempt to recompile Write-Log "Attempting to recompile invalid objects..." $recompileSql = @" SET SERVEROUTPUT ON BEGIN DBMS_UTILITY.COMPILE_SCHEMA('CONTAFIN_ORACLE', FALSE); END; / EXIT; "@ Invoke-SqlPlus -OracleHome $oraHome -ServiceName $ServiceName ` -Username "SYSTEM" -Password $SystemPassword -SqlCommand $recompileSql -Silent # Recheck invalid count $recheckCounts = Get-SchemaObjectCount -OracleHome $oraHome -ServiceName $ServiceName ` -Password $SystemPassword -SchemaName "CONTAFIN_ORACLE" $recheckInvalid = if ($recheckCounts['INVALID']) { $recheckCounts['INVALID'] } else { 0 } if ($recheckInvalid -lt $afterInvalid) { Write-LogSuccess "Recompilation fixed $($afterInvalid - $recheckInvalid) objects" } if ($recheckInvalid -gt 0) { Write-LogWarning "Still $recheckInvalid invalid objects remaining" } } else { Write-LogSuccess "No invalid objects" } # Summary Write-LogSection "Import Complete" if ($process.ExitCode -eq 0) { Write-LogSuccess "CONTAFIN_ORACLE schema imported successfully!" } else { Write-LogWarning "Import completed with warnings (exit code: $($process.ExitCode))" } Write-Log "" Write-Log "Summary:" Write-Log " Dump file: $dumpFileName ($dumpSizeMB MB)" Write-Log " Service: $ServiceName" Write-Log " Duration: $([math]::Round($duration.TotalMinutes, 2)) minutes" Write-Log " Objects: $afterTotal" Write-Log " Import log: $importLogPath" Write-Log "" Write-Log "Next steps:" Write-Log " 1. Run 04-create-synonyms-grants.ps1 to create public synonyms" Write-Log " 2. Run 05-import-companies.ps1 to import company schemas" Close-LogFile -Success ($process.ExitCode -eq 0) exit $process.ExitCode } catch { Write-LogError "Import failed: $_" Write-LogError $_.ScriptStackTrace Close-LogFile -Success $false exit 1 }