Vserver v4.3
Ivan Smahin
ivan_smahin at paradigmasoft.com
Mon Apr 5 05:27:35 CDT 2010
Hello Stan,
Monday, April 5, 2010, 12:52:34 PM, you wrote:
> Hi Ivan,
> The function code is:
> aCursor = inDatabase.SQLSelect( aQuery,
> EVCursorLocation.kServerSide, EVLockType.kNoLocks, EVCursorDirection.kRandom )
> If aCursor <> nil then
> If aCursor.RecordCount > 0 then
> Do
> aCurrency = aCursor.ULongField("Account_CurrencyRecord").Value
> aBalance = aCursor.DoubleField("Account_Balance").Value
> aResult = aResult + ConvertToDefaultCurrency( inDatabase,
> aBalance, aCurrency ) <----- CRASH HERE AFTER 6 OR 7 ITERATIONS
> Loop Until not aCursor.NextRecord()
> end if
> end if
Ok, you extract aCurrency and aBalance values and pass it to some
function in the loop.
> It crashed inside the 'ConvertToDefaultCurrency' function. This is function code is:
I guess inCurrency is a passed aCurrency - yes?
> If inCurrency > 0 then
> aRate = inDatabase.mCurrency.GetRate( inCurrency )
> aDirection = inDatabase.mCurrency.GetCurrencyDirection( inCurrency )
> If aRate = 0 then aRate = 1
> If aDirection = 0 then
> Return inNumber / aRate
> elseif aDirection = 1 then
> Return inNumber * aRate
> end if
> else
> Return inNumber
> end if
> inDatabase.mCurrency.GetRate code is:
> If isValid( inRec ) then
> Return mRate.Value
> end if
>
mRate is a field - right?
But who load proper value into this field?
> inDatabase.mCurrency.GetCurrencyDirection is:
> If isValid( inRec ) then
> Return mDirection.Value
> end if
> In both cases isValid code is:
> If RecordExists( inRec ) then
> RecID = inRec
> Return True
> else
> Return False
> end if
> Stan
Ok, let me explain
Firstly API way is not a best choice in client-server environment due
to the following reasons:
1. It could be a lot of calls which must be passed to the server.
Finally it might be more time than using SQL-way.
I mean it would not be so time-efficient as in a local mode.
So SQL-way is preferred choice here.
2. Your loop might be interrupted by another user in any moment.
And, say, current record might be changed, moved, even deleted.
Another user may alter the table or even drop it... and so on.
In most of cases you are able to write some additional code to
guarantee than nothing "bad" may happen but it would not be
a "general" solution anyway.
So it is one more vote for SQL-way.
Short note - you have a guarantee that each particular API-method
call will NOT be interrupted by another user.
Example:
SetBLank
AddRecord
It could be interruption between that commands but not inside of
any of them.
So when you call SqlExecute( "..." ) it could not be interrupted
too. And most of people prefer to keep the business-logic inside
the database using stored procedures. There are many advantages...
So actually call might be as strong as
SqlExecute( "call mySp1( param1, param2)" );
Getting back to your code...
Can you send me the app and db for testing?
Just hard to say why it work 6-7 times and then crashed.
--
Best regards,
Ivan Smahin
Senior Software Engineer
Paradigma Software, Inc
Valentina - The Ultra-Fast Database
http://www.valentina-db.com
More information about the Valentina
mailing list