Files
ROMFASTSQL/proxmox/lxc108-oracle/roa-windows-setup/scripts/03-import-contafin.ps1
Marius ec66377e0f fix(oracle): calea DMPDIR devine parametru; sqlnet.ora ajunge unde e citit
Gasite la instalarea de productie VADECO (Oracle 21c XE, Windows Server 2019).

1. Pe serverul VADECO procesul Oracle nu poate atinge nicio cale de pe C:,
   nici macar C:\Windows\Temp, desi ACL-urile sunt corecte si serviciul ruleaza
   ca NT SERVICE\OracleServiceXE. D: merge cu exact acelasi grant. Calea DMP
   era insa hardcodata "C:\DMPDIR" in 01, 02, 05, 06 si in biblioteca, deci
   instalarea nu se putea muta. Acum e parametrul -DmpDir, expus ca /dmpdest:
   in FAZA1.cmd si FAZA2.cmd si transmis tuturor pasilor.

   Cel mai perfid era pasul 02: recrea DIRECTORY DMPDIR pe 'C:\DMPDIR' peste
   valoarea pusa de 01. Chiar cu restul instalarii mutata, SYS.NEWSCHEMA ar fi
   cautat FIRMANOUA.dmp in alta parte, iar adaugarea unei firme noi ar fi picat
   peste luni, fara legatura vizibila cu instalarea.

2. New-OracleDirectory compara doar siruri de caractere: verifica ce scrie in
   dba_directories, nu daca baza chiar poate scrie acolo. Acum face un
   UTL_FILE round-trip si esueaza pe loc, cu explicatia cauzei. Inainte,
   directorul inutilizabil trecea drept bun si importul cadea abia in impdp cu
   ORA-29283, la zeci de linii distanta. Valoarea de retur nici nu era
   verificata in 01/03/06 - de aici si "True" ratacit in log.

3. Instalarea ROAClient seteaza TNS_ADMIN de masina spre instantclient-ul ei.
   Serviciul Oracle mosteneste variabilele de masina, deci citea sqlnet.ora de
   acolo - unde nu exista niciunul - si nu din Oracle Home, unde il scria pasul
   01. Compatibilitatea pentru clienti vechi nu se aplica, iar statiile ar fi
   primit ORA-28040 cu fisierul scris corect, in locul gresit. Pasul 01 scrie
   acum sqlnet.ora si in TNS_ADMIN cand difera.

4. Pasul 05 lega schemele de DMP-uri cu "^$schema[_\.]", deci schema DANUBE
   putea primi DANUBE_20200914.dmp - datele altei firme, fara avertisment.
   Numele exact are acum intaietate, prefixul se accepta doar daca e unic, iar
   ambiguitatea se raporteaza.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SzF1hf4aFS1tmJWpPMiwGp
2026-08-25 21:18:43 +03:00

340 lines
12 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. 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"
}
# Valoarea de retur nu era verificata - de aici si "True" ratacit in log.
# Mai rau: cand directorul nu era utilizabil, importul mergea mai departe si
# cadea abia in impdp cu ORA-29283, la zeci de linii distanta de cauza.
if (-not (New-OracleDirectory -OracleHome $oraHome -ServiceName $ServiceName `
-Password $SystemPassword -DirectoryName "DMPDIR" -DirectoryPath $DmpDir)) {
throw "Directorul Data Pump DMPDIR ($DmpDir) nu e utilizabil de catre baza. Vezi mesajele de mai sus."
}
# 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
}