Subject | Update success |
---|---|
Author | Andy Canfield |
Post date | 2001-06-26T11:24:31Z |
My C++ classes incorporate a function named "SQLWriteObject()" which writes
a C++ object into the row of a table. For example, class Station defines
Station::SQLWriteObject(); if the data member StationIdent has the value
"AT" then SQLWriteObject should put the data into the STATION table where
primary key STATIONIDENT has the value "AT".
SQLWriteObject(), of course, does not know whether that row is already in
the table or not. I could search for STATIONIDENT='AT' and then do an UPDATE
... WHERE or an INSERT depending on whether the row was found or not. But
that would be an extra database access and would presumably slow things
down.
My fix was to define a function SQLInsertOrUpdate() which will try one and
then, if that fails, try the other. Using the API, it tries to do an INSERT
and, if the insert fails because the row is already there, does an UPDATE.
If there is a 50/50 chance that the row is present already then the average
number of database commands will be 1.5 -- the row is present the INSERT
succeeds in 1 step, if the row is absent the INSERT fails and the UPDATE
succeeds in 2 steps.
My original specification for SQLInsertOrUpdate() called for a parameter
saying which I should try first. If I'm reading data in one situation, then
the row is probably not present and I should try the INSERT first. If I'm
reading data in a different situation then the row is probably present and I
should try the UPDATE ... WHERE first. That way reasonable prediction should
get the workload down from 1.5 to nearly 1.
The problem was that SQL considers the UPDATE ... WHERE command to succeed
even if the WHERE clause matches nothing at all. So I have no way to know
whether the UPDATE found what it was looking for. I can INSERT, and then
UPDATE if the INSERT fails; I would like to be able to UPDATE and then
INSERT if the UPDATE 'fails'.
Is there an efficient way in the API to find out whether the UPDATE command
changed anything?
a C++ object into the row of a table. For example, class Station defines
Station::SQLWriteObject(); if the data member StationIdent has the value
"AT" then SQLWriteObject should put the data into the STATION table where
primary key STATIONIDENT has the value "AT".
SQLWriteObject(), of course, does not know whether that row is already in
the table or not. I could search for STATIONIDENT='AT' and then do an UPDATE
... WHERE or an INSERT depending on whether the row was found or not. But
that would be an extra database access and would presumably slow things
down.
My fix was to define a function SQLInsertOrUpdate() which will try one and
then, if that fails, try the other. Using the API, it tries to do an INSERT
and, if the insert fails because the row is already there, does an UPDATE.
If there is a 50/50 chance that the row is present already then the average
number of database commands will be 1.5 -- the row is present the INSERT
succeeds in 1 step, if the row is absent the INSERT fails and the UPDATE
succeeds in 2 steps.
My original specification for SQLInsertOrUpdate() called for a parameter
saying which I should try first. If I'm reading data in one situation, then
the row is probably not present and I should try the INSERT first. If I'm
reading data in a different situation then the row is probably present and I
should try the UPDATE ... WHERE first. That way reasonable prediction should
get the workload down from 1.5 to nearly 1.
The problem was that SQL considers the UPDATE ... WHERE command to succeed
even if the WHERE clause matches nothing at all. So I have no way to know
whether the UPDATE found what it was looking for. I can INSERT, and then
UPDATE if the INSERT fails; I would like to be able to UPDATE and then
INSERT if the UPDATE 'fails'.
Is there an efficient way in the API to find out whether the UPDATE command
changed anything?