Key fixes: - Add Run.cmd/RunAll.cmd wrappers with ExecutionPolicy Bypass - Add Get-ListenerHost() to auto-detect listener IP address - Fix impdp connection using EZConnect format (host:port/service) - Add parallel=1 for Oracle XE compatibility - Fix Write-Log to accept empty strings with [AllowEmptyString()] - Fix Get-SchemaObjectCount regex for Windows line endings (\r\n) - Fix path comparison for DMP file copy operation - Add GRANT EXECUTE ON SYS.AUTH_PACK TO PUBLIC for PACK_DREPTURI - Fix VAUTH_SERII view to use SYN_NOM_PROGRAME (has DENUMIRE column) - Add sections 10-11 to grants-public.sql for SYS object grants Tested on VM 302 (10.0.20.130) with Oracle XE 21c. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
318 lines
11 KiB
PowerShell
318 lines
11 KiB
PowerShell
#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. Required.
|
|
|
|
.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 = $true)]
|
|
[ValidateScript({ Test-Path $_ })]
|
|
[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"
|
|
|
|
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
|
|
}
|