EPOC32, DBMS SQL hints and tips |
From this page I just wanted to share some tips I've picked up when programming with the new EPOC32 DBMS and SQL methods. If you don't know what either are it's best you hit the back button now !
When porting my Reviser app from the Series 3x to the Series 5, it became apparent that the DBMS/SQL documentation provided by Psion PLC was ... lacking somewhat. While the documentation of the SQL interface was syntactically correct, it didn't provide adequate examples, nor did the documentation for the index creation methods in dbase.oxh.
A lot of trial and error was called for, along with a smattering of help from a few other programmers on comp.sys.psion.programmer.
The first thing to remember ?
always :
INCLUDE "Dbase.oxh"
CREATE "TestData FIELDS emp_id,salary,bonus TO salaries",S,emp$,dosh,bonus CLOSE CREATE "TestData FIELDS emp_id,address1,address2,postcode TO addresses",A,emp$,add1$,add2$,pc$ CLOSENote : the mapping of field names to variable names can differ - the field names (emp_id, salary etc) are used in SQL constructs, while the variable names (emp$, dosh etc) are used when assigning to and from the variables ie S.dosh=100000.0
There is nothing to stop you now opening two tables simultaneously and adding data etc.
OPEN "TestData SELECT * FROM salaries",S,emp_id$,dosh,bonus USE S INSERT S.emp_id="A667663-HJ" S.dosh=30000.0 S.bonus=4000.0 PUT CLOSENote the "USE" statement. When dealing with multiple views, open at the same time, be liberal with "USE", as it may avoid confusion and errors, as to which view/table you are using.
OPEN "TestData SELECT emp_id,bonus FROM salaries",S,emp_id$,bonus USE S PRINT COUNT WHILE (NOT EOF) PRINT S.emp_id$,S.bonus NEXT ENDWH CLOSE
The trick is to limit the size of a string field you wish to use as a key, at table creation time ie :
CREATE "TestData FIELDS emp_id(20) etc etc",A,emp$,etc etcThen to create the index :
LOCAL key1& key1&=DbNewKey&: DBSetComparison:(key1&,kDbCompareNormal&) DbAddField:(key1&,"emp_id",kDbAscending&) DbCreateIndex:("Ind1",key1&,"TestData","salaries")
LOCAL salaryVal,bonuVal LOCAL buff$(255) salaryVal=50000.0 bonusVal=5000.0 buff$="salary > "+GEN$(salaryVal,8) buff$=buff$+" AND bonus < "+GEN$(bonusVal,8) OPEN "TestData SELECT emp_id FROM salaries WHERE "+buff$,S,emp_id$ USE S PRINT COUNT WHILE (NOT EOF) PRINT S.emp_id$ NEXT ENDWH CLOSENote the way in which the SQL can be dynamically constructed using strings (buff$). Also note that after a "SELECT,WHERE" clause has opened a view on a table, COUNT returns the number of matching records, and not the total number of records in that table.
OPEN "TestData SELECT emp_id, salary WHERE emp_id LIKE 'A*'",S,emp_id$,doshor :
buff$="A*" OPEN "TestData SELECT emp_id, salary WHERE emp_id LIKE '"+buff$+"'",S,emp_id$,doshSimple yes, but I went round and round in circles ...
The answer was to switch on automatic compaction using
SETFLAGS KAutoCompact&Now when the same file is created, it's size still grows to 300k as records are added, but when it is closed it is compacted down to the expected 30k. If anyone knows how to keep the size down at all times let me know !
©1998 Phil Whiles |
Go Home ! | Last revised: 26th May '98 |