Subject RE: [IBO] TIB_Query and InsertSQL
Author Helen Borrie
At 10:43 PM 10/04/2007, you wrote:
> >I'm not seeing this at all, so I suggest there might be something
> >wonky in your SQL. IBO has had a lot of tightening to comply with
> >the corrections in SQL in Firebird 2. This is going to show up a lot
> >of off-beam SQL in client apps that used to be forgiven.
>
> >Let's see the following:
>
> >-- The SELECT statement
>
>
>SELECT MAINTENANCEITEMNUMBER
>
> , RECEIVEDDATE
>
> , RESOLVEDON
>
> , CENTERNUMBER
>
> , BUSINESSUNITNUMBER
>
> , CREATIONDATE
>
> , MODIFICATIONDATE
>
> , RECEIVEDBYPERSONNUMBER
>
> , PRIORITYNUMBER
>
> , CHECKLISTNUMBER
>
> , CENTERAREANUMBER
>
> , SITUATION
>
> , ACTIONLISTCOUNT
>
> , CENTERNAME
>
> , RECEIVEDBYPERSONNAME
>
> , OPERSONNUMBER
>
> , ACTIONLISTPENDINGCOUNT
>
> , CENTERAREADESCRIPTION
>
> , CHECKLISTDESCRIPTION
>
> , LatestPendingAssignedTask
>
> FROM GetMaintenanceForPerson1(:PersonNumber,:RequestType)
>
>
>
> >-- The InsertSQL statement
>
>
>INSERT INTO MaintenanceRequest
>
> ( MaintenanceItemNumber
>
> , ReceivedDate
>
> , ResolvedOn
>
> , CenterNumber
>
> , BusinessUnitNumber
>
> , ReceivedByPersonNumber
>
> , PriorityNumber
>
> , CheckListNumber
>
> , CenterAreaNumber
>
> , Situation)
>
> VALUES ( :MaintenanceItemNumber
>
> , :ReceivedDate
>
> , :ResolvedOn
>
> , :CenterNumber
>
> , :BusinessUnitNumber
>
> , :ReceivedByPersonNumber
>
> , :PriorityNumber
>
> , :CheckListNumber
>
> , :CenterAreaNumber
>
> , :Situation)
>
>
>
>Here is the update and delete SQL that work do their job correctly
>
>
>
>UPDATE MaintenanceRequest
>
> SET ReceivedDate = :ReceivedDate
>
> , RESOLVEDON = :ResolvedOn
>
> , SITUATION = :Situation
>
> , ReceivedByPersonNumber = :ReceivedByPersonNumber
>
> , CenterNumber = :CenterNumber
>
> , CENTERAREANUMBER = :CenterAreaNumber
>
> , CHECKLISTNUMBER = :CheckListNumber
>
> WHERE MAINTENANCEITEMNUMBER = :MaintenanceItemNumber
>
>
>
>DELETE FROM MaintenanceRequest WHERE MAINTENANCEITEMNUMBER =
>:MaintenanceItemNumber
>
>
>
> >-- The KeyLinks for the set
>
>
>
>MAINTENANCEITEMNUMBER
>
>
> >Helen
>
>
>
>
>
>What bothers me is the fact that the SQL Monitor blows up posting an insert:
>
>
>
>Project Maintenance.exe raised exception class EAccessViolation with message
>‘Access violation at address 00000000. Read of Addreess 00000000’.
>
>
>
>This is what does show up in the monitor screen after clearing the error
>message. The MaintenanceItemNumber to be inserted is 497 (IBO fetched the
>value after the insert) but the monitor reports before it blows up 491 which
>is the value of the MaintenanceItemNumber for the current selected row when
>the insert was executed (and the other column values also match that row as
>well).
>
>
>
>/*---
>
>EXECUTE STATEMENT
>
>TR_HANDLE = 3371056
>
>STMT_HANDLE = 18677972
>
>PARAMS = [ Version 1 SQLd 10 SQLn 10
>
> [MAINTENANCEITEMNUMBER] = 491 ß
>
> [RECEIVEDDATE] = '09 Apr 2007 09:13:53 2550'
>
> [RESOLVEDON] = <NULL>
>
> [CENTERNUMBER] = 14
>
> [BUSINESSUNITNUMBER] = 2
>
> [RECEIVEDBYPERSONNUMBER] = 121
>
> [PRIORITYNUMBER] = 1
>
> [CHECKLISTNUMBER] = 3
>
> [CENTERAREANUMBER] = 4
>
> [SITUATION] = 'The Situation' ]
>
>
>
>SECONDS = 0.010
>
>
>
>ERRCODE = 335544665
>
>----*/

That is unique_key_violation. Your mistake here
is due to your handling of the primary key for
the new record. Because there is no underlying
table to the dataset, you cannot use a parameter
for inserting it via a DSQL statement. (This
should not have worked previously....I think
there is some other change you haven't mentioned...)


In a well-ordered world, you would have a
generator for the primary key and a Before Insert
trigger populating it. In this case you *can*
use a DSQL INSERT statement for your InsertSQL
and omit the primary key from the insert
statement entirely. Alternatively, you could use
GeneratorLinks and have IBO fetch the value automatically at BeforeInsert.

If you are creating the PK by some other means,
you still have a couple of alternatives.

-- If you are doing it client side (NOT
RECOMMENDED!!) then do so, and apply it, in the
dataset's BeforeInsert handler.

-- If you have some different, server-side
mechanism for creating the primary key value then
you must write a stored procedure to do the
insert, with an input parameter set that is
sufficient to pick up the needed values from the
current Fields[] array of the dataset but NOT the
primary key. Your InsertSQL would then be an
EXECUTE PROCEDURE (:param1, :param2, :etc...)
statement, making sure that you match the
parameter placeholder names with the
corresponding identifiers in the output set.

Helen