Delphi 3/BDE 4.00/MS-SQL 6.5 - Problem w/Changing Field Value

Project:    Flat Rate Book Publisher
Parameters:
  Create a client/server program to facilitate the publication
  of multiple flat rate books, allowing functionality for a
  variable number of pricing columns and task groups.

Programming Language:
  Delphi 3

DBMS:
  Microsoft SQL Server v6.5

Client/Server Interface:
  Borland Database Engine and ODBC

------

I am currently coding the portion of the above detailed
program that allows the user to specify which user-defined
pricing columns are assigned to a particular flat rate
book.  The user must also be able to specify the order in
which the pricing columns are displayed or printed.

To accomplish this, I have several tables setup in a MS-SQL
database (pertinant tables shown below):

frBooks
  RecordID     Int          Non-Null Identity    Primary Key
  Description  Char(50)     Non-Null
  GroupCount   Int          Non-Null
  ColumnCount  Int          Non-Null
  TaxableItems Char(1)      Non-Null
  TaxRate      Decimal(5,2) Non-Null

frColumns
  RecordID     Int          Non-Null Identity    Primary Key
  Description  Char(15)     Non-Null
  TripFee      Money        Non-Null
  Margin       Decimal(5,3) Non-Null
  Rounding     Char(1)      Non-Null

frColumnAssignments
  RecordID     Int          Non-Null Identity    Primary Key
  BookID       Int          Foreign Key (frBooks.RecordID)
  ColumnID     Int          Foreign Key (frColumns.RecordID)
  Position     Int          Non-Null

A flat rate book is defined in frBooks.  Columns are defined in
frColumns.  Columns are assigned to flat rate books through a
Column Assignment record.

frColumnAssignments.Position specifies an integer value by which
to sort the columns when displaying or printing in the context
of the flat rate book.

Obviously, to allow the user to specify the order in which the
columns are displayed, this Position field must be able to
change.

To accomplish this, I am working with two queries:

qryColumnAssignments
  A cursor containing the entire list of column
  assignments.

qryColumnAssignments.SQL =
  SELECT * FROM frColumnAssignments

qryColumnsAssigned
  A cursor containing a list of columns assigned
  to the current flat rate book, sorted by position.

qryColumnsAssigned.SQL =
  SELECT frColumns.Description, frColumnAssignments.*

  FROM   frColumnAssignments INNER JOIN frColumns

  ON     frColumnAssignments.ColumnID = frColumns.Description

  WHERE  frColumnAssignments.BookID = :SelectedBookID

  ORDER BY frColumnAssignments.Position

The code that allows the user to do so is shown below:

  // Change the position of an assigned column for a flat rate book.
  procedure ChangePosition(Direction : SmallInt);
  const
  dirDown     = 0;
  dirUp       = 1;

  var
  RecordID    : Array[1..2] of LongInt;
  Position    : Array[1..2] of LongInt;
  begin
  with dmMain do
       begin
       // Disable related controls
       qryColumnsAssigned.DisableControls;

       // Collect information on the column to be moved.
       RecordID[1] := qryColumnsAssignedRecordID.Value;
       Position[1] := qryColumnsAssignedPosition.Value;

       // Move the cursor to the column assignment record that
       // the we want to move ahead/behind of.
       Case Direction of
            dirUp   : if (not(qryColumnsAssigned.BOF)) then
                         qryColumnsAssigned.Prior
                         else
                         Exit;
            dirDown : if (not(qryColumnsAssigned.EOF)) then
                         qryColumnsAssigned.Next
                         else
                         Exit;
            else         Exit;
            end;

       // Collect information on the column to be moved
       // ahead/behind of.
       RecordID[2] := qryColumnsAssignedRecordID.Value;
       Position[2] := qryColumnsAssignedPosition.Value;

-->    // Find the column assignment record to be moved, and change
       // the value of the Position field to that of the column to
       // be moved ahead/behind of.
       qryColumnAssignments.Filter := 'RecordID = ' + InttoStr(RecordID[1]);
       qryColumnAssignments.FindFirst;

       qryColumnAssignments.Edit;
       qryColumnAssignmentsPosition.Value := Position[2];
       qryColumnAssignments.Post;

       // Find the column assignment record of the column to be
       // moved ahead/behind of and change the value of the Position
       // field to that of the column that was just moved.
       qryColumnAssignments.Filter := 'RecordID = ' + InttoStr(RecordID[2]);
       qryColumnAssignments.FindFirst;

       qryColumnAssignments.Edit;
       qryColumnAssignmentsPosition.Value := Position[1];
       qryColumnAssignments.Post;

       // Commit changes to the database and refresh related queries.
-->    dbFlatRate.ApplyUpdates([qryColumnAssignments]);
       RefreshQuery(qryColumnAssignments);    // Refreshes the cursor
       RefreshQuery(qryColumnsAssigned);

       // Move cursor to the column record that was moved.
       qryColumnsAssigned.Filter := 'RecordID = ' + InttoStr(RecordID[1]);
       qryColumnsAssigned.FindFirst;

       // Enable related controls
       qryColumnsAssigned.EnableControls;
       end;
  end; // Procedure ChangePosition

This method functions correctly, but in any session that it is called,
the following error occurs:

FLATRATE caused an invalid page fault in
module KERNEL32.DLL at 0137:bff857e7.
Registers:
EAX=c001f0cc CS=0137 EIP=bff857e7 EFLGS=00010202
EBX=006bfcc4 SS=013f ESP=005bffc4 EBP=005c0034
ECX=816040a0 DS=013f ESI=005c0274 FS=0f97
EDX=388b5708 ES=013f EDI=4da392fa GS=0000
Bytes at CS:EIP:
53 56 89 4d f8 57 8b 41 40 8b 75 08 89 45 ec 83
Stack dump:

I have traced the offending code to the following block:

-->    // Find the column assignment record to be moved, and change
       // the value of the Position field to that of the column to
       // be moved ahead/behind of.
       qryColumnAssignments.Filter := 'RecordID = ' + InttoStr(RecordID[1]);
       qryColumnAssignments.FindFirst;

       qryColumnAssignments.Edit;
       qryColumnAssignmentsPosition.Value := Position[2];
       qryColumnAssignments.Post;

       // Find the column assignment record of the column to be
       // moved ahead/behind of and change the value of the Position
       // field to that of the column that was just moved.
       qryColumnAssignments.Filter := 'RecordID = ' + InttoStr(RecordID[2]);
       qryColumnAssignments.FindFirst;

       qryColumnAssignments.Edit;
       qryColumnAssignmentsPosition.Value := Position[1];
       qryColumnAssignments.Post;

       // Commit changes to the database and refresh related queries.
-->    dbFlatRate.ApplyUpdates([qryColumnAssignments]);

I do not see anything wrong with this code, but I am obviously missing
something.  Any assistance would be appreciated.

Michael J. Church, IT Specialist         (219)295-6844 x 24
Church Plumbing and Heating, Inc.        (219)522-9834 Fax
mjchu...@mc2services.com