DEV Community

Query Filter
Query Filter

Posted on

rec

!/bin/bash

Usage: ./verify_table_checksum.sh mytable.ctl

Compares Sybase vs Oracle data fidelity (excluding FILLER/IDENTITY columns, normalizing nulls/spaces)

if [ $# -ne 1 ]; then
echo "Usage: $0 "
exit 1
fi

CTL_FILE="$1"

--- Extract table name (uppercase, strip extension)

TABLE_NAME=$(basename "$CTL_FILE" .ctl | tr '[:lower:]' '[:upper:]')

--- Extract filler/ignored columns (any line containing 'FILLER' or 'IDENTITY')

FILLER_COLS=$(grep -iE 'FILLER|IDENTITY' "$CTL_FILE" | awk '{print toupper($1)}' | tr '\n' ' ')

--- Extract all column names (skip comments/blank lines)

ALL_COLS=$(grep -v -iE 'FILLER|OPTIONS|INTO|FIELDS|INFILE|LOAD|REPLACE|TRAILING|^ *$' "$CTL_FILE"
| grep -v '^[#;/]'
| sed 's/[(),]//g'
| awk '{print toupper($1)}')

--- Build normalized include list (exclude filler/identity)

COLUMNS_TO_INCLUDE=()
for col in $ALL_COLS; do
skip=false
for filler in $FILLER_COLS; do
[[ "$col" == "$filler" ]] && skip=true && break
done
$skip || COLUMNS_TO_INCLUDE+=("$col")
done

--- Connection settings

SYBASE_USER="sa"
SYBASE_PASS="yourpass"
SYBASE_DB="MYDB"

ORACLE_USER="oracle_user"
ORACLE_PASS="oracle_pass"
ORACLE_SID="ORCL"

--- Temp SQL files

TMP_SYB=$(mktemp)
TMP_ORA=$(mktemp)

--- Sybase SQL with normalization (NULL→'', trim spaces)

{
echo "SELECT CHECKSUM_AGG(BINARY_CHECKSUM("
for i in "${!COLUMNS_TO_INCLUDE[@]}"; do
[[ $i -gt 0 ]] && echo ","
echo "ISNULL(LTRIM(RTRIM(${COLUMNS_TO_INCLUDE[$i]})),'')"
done
echo ")) AS table_checksum FROM $TABLE_NAME"
} > "$TMP_SYB"

--- Oracle SQL with same normalization

{
echo "SET HEADING OFF"
echo "SET FEEDBACK OFF"
echo "SET PAGESIZE 0"
echo "SET TRIMSPOOL ON"
echo "SELECT STANDARD_HASH(LISTAGG("
for i in "${!COLUMNS_TO_INCLUDE[@]}"; do
[[ $i -gt 0 ]] && echo " || '~' ||"
echo "NVL(NULLIF(TRIM(${COLUMNS_TO_INCLUDE[$i]}),''),'')"
done
echo ", '~') WITHIN GROUP (ORDER BY 1), 'MD5') AS table_checksum FROM $TABLE_NAME;"
echo "EXIT;"
} > "$TMP_ORA"

--- Compute checksums

syb_sum=$(isql -U "$SYBASE_USER" -P "$SYBASE_PASS" -S "$SYBASE_DB" -b -Q "$(cat "$TMP_SYB")" | tail -n1 | tr -d '[:space:]')
ora_sum=$(sqlplus -s "$ORACLE_USER/$ORACLE_PASS@$ORACLE_SID" @"$TMP_ORA" | tail -n1 | tr -d '[:space:]')

--- Compare

timestamp=$(date '+%Y-%m-%d %H:%M:%S')
if [ -n "$syb_sum" ] && [ "$syb_sum" == "$ora_sum" ]; then
echo "✅ [$timestamp] MATCH for $TABLE_NAME"
else
echo "❌ [$timestamp] MISMATCH for $TABLE_NAME"
echo "Sybase: $syb_sum"
echo "Oracle: $ora_sum"
echo "$timestamp $TABLE_NAME SYBASE=$syb_sum ORACLE=$ora_sum" >> checksum_mismatches.log
fi

--- Cleanup

rm -f "$TMP_SYB" "$TMP_ORA"

Top comments (0)