Job using the loadp.bat script on Windows aborts with err=512 when there are discarded rows.

Document ID : KB000088438
Last Modified Date : 14/04/2018
Show Technical Document Details
Issue:
Applicable to Applications Manager Versions:  v8.0, v9
Error Message Details:
NTSPAWN pid 440:1b8
JOBID 12424.00
Spawned process with ID 10888 2a88
return status=512err=512

end of D:\am8agnt\exec\BODY2.BAT status 512 Mon 01/12/2015 14:17:10.02
err is:'512'
Symptoms
When using Applications Manger's loadp.bat script on a Windows Agent that runs a SQL*Loader job that contains discarded records you receive the above 512 errors and the job goes to an ABORTED status. However, the job does run successfully and does load the correct data into the table.

Cause
Applications Manager's loadp.bat script is using Perl's error variable '$?' to return the errno if one of the calls fail. This errno is stored into a 16 bit integer. When the SQL*Loader job runs and has discarded rows you should get a warning message and it should exit with an exit code of 2. However, when '$?' is evaluated on Windows, it is evaluated as the binary value of 0000001000000000, which is 512 instead of 2. When shifted to the right by 8 bits, you get 00000010, which represents "2" and is the value we expect from the SQL*Loader for warning messages
 

 
Resolution:

Workaround
Make a copy of the original %AW_HOME%\loadp.bat script and call it loadp1.bat.  Add additional error trapping as outlined below (or download the modified loadp1.bat script attached to this knowledge entry), and change the Program Name in your SQL*Loader job to use the loadp1.bat script.
Add 4 lines after line 44 or original loadp.bat script:
my $ldrerr = 0;
my $holderr = 0;
my $ntserr = 0;
my $cored = 0;

After line 289 (`$SQLOPER_HOME\\c\\ntspawn "$awsqlload parfile=$seq_no\.par "`;)
Replaced lines 290 and 291
    if ($? != 0) { $err = $?; }
                print "return status=$err";
With these lines:
    foreach (sort keys %ENV) { print "$_ = $ENV{$_}\n"; }
    if ($? != 0)
    {
    $holderr = $?;
    print "hold error is $holderr \n";
    $ldrerr = $holderr >> 8;
    print "ldr error is $ldrerr \n";
    $ntserr = $holderr & 127;
    $cored = $holderr & 128;
   if ($ntserr != 0 or $cored != 0)
       { $err = $holderr & 255; }   
    elsif ( $ldrerr == 3 or $ldrerr == 4 )
        { $err = $holderr; }
    # end if   
    print "error variables coming from ntspawn sqlldr\n";
    print "ntspawn error $ntserr - core dump $cored - sqlldr $ldrerr\n\n";
    }   
    print "return status of sqlldr=$err\n";