kbmsql – structured query language for your memory...
TRANSCRIPT
kbmMemTable is known for being a very feature rich and fast memory table.
It's a memory storage of row/field oriented data. kbmMemTable contains lots of features for searching, filtering, sorting and grouping the data contained in it, just like a database like Oracle, MSSQL etc. However apart from the fact that a kbmMemTable holds one single table, a big difference between Oracle/MSSQL etc and kbmMemTable is that Oracle/MSSQL supports (actually primarily uses) the SQL language for searching and manipulating data in the tables. For years, kbmMemTable was not able to understand proper SQL syntax, but we introduced a free, bundled add-on for kbmMemTable Standard Edition and kbmMemTable Professional Edition that we named kbmSQL. kbmSQL enables support for a large subset of the SQL language for any number of kbmMemTables you have. Over time kbmSQL is expected to evolve to support an even larger subset of the current SQL standard.
After having downloaded and installed kbmMemTable and kbmSQL, you will find several components in the kbmMemTable section.
What’s a memory table?
So how to use it then?
As usual you will find TkbmMemTable, TkbmBinaryStreamFormat, TkbmCSVStreamFormatter and TkbmThreadDataset (which is
) components. And then as something new - TkbmMemSQL.
available for backwards compatibility and rarely used
TkbmMemSQL is in it self a memory table, that is based on TkbmMemTable, and will be the container for any results coming from a SQL statement. Those results can thus be further manipulated or presented in the same way as a regular TkbmMemTable instance by using it as a source of data for some other procedure or connect it to data aware controls. To make TkbmMemSQL tick, we need to give it two things to work with… data and a SQL statement. The raw data is provided for it via other datasets. Currently kbmMemTable is supported as a data provider, but kbmSQL has been designed with extesibility in mind, since other data providers may be added later on. So let's start with a sample application.
I have added a kbmMemTable (for the raw data), a kbmMemSQL component for doing our SQL, and a couple of grids to show the raw and result data, and finally a button that we will click to execute the SQL.I’ll make it simple and just put the code we need into the Execute SQL button.
kbmSQL – Structured Query Language for your memory table
You may already have used kbmMemTable in your applications. If not, then its certainly about time to try it out. You can download kbmMemTable CodeGear Edition for free from after registering, but please notice that only latest version of Delphi is supported with kbmMemTable CodeGear Edition. If you would like to use kbmMemTable for other versions of Delphi, C++Builder or FPC, you need to get kbmMemTable Standard Edition from
. Its only US $30 and includes source and kbmSQL, which this article is about.
www.myc4d.com
www.components4developers.com
uses
procedurebegin
50
50
120 10.10
15 20.10
10 10.10
33 10.10
12 10.10
99 20.10
19 10.10
143 20.10
199 10.10
end
// Make sure to include this unit to have support for kbmMemTable registered in kbmSQL.
// Prepare some raw data to work on.
// Register kbmMemTable1 as source for kbmMemSQL1.// Notice that we have given kbmMemTable1 a name that identifies it in SQL (table1).
// Prepare some simple SQL.
;
. ( : );
. ;
. .( , , );
. .( , , );
. .( , );
. .( , );
. ;
. ;
.([ , , , ]);
.([ , , , ]);
.([ , , , ]);
.([ , , , ]);
.([ , , , ]);
.([ , , , ]);
.([ , , , ]);
.([ , , , ]);
.([ , , , ]);
. . ;
. . ( , );
. ( );;
kbmSQLMemTableAPI
TForm1 Button1Click Sender TObject
kbmMemTable1 ResetkbmMemTable1 FieldDefs Add
ftStringkbmMemTable1 FieldDefs Add
ftStringkbmMemTable1 FieldDefs Add
ftFloatkbmMemTable1 FieldDefs Add
ftFloatkbmMemTable1 CreateTablekbmMemTable1 OpenkbmMemTable1 AppendRecord
kbmMemTable1 AppendRecord
kbmMemTable1 AppendRecord
kbmMemTable1 AppendRecord
kbmMemTable1 AppendRecord
kbmMemTable1 AppendRecord
kbmMemTable1 AppendRecord
kbmMemTable1 AppendRecord
kbmMemTable1 AppendRecord
kbmMemSQL1 Tables ClearkbmMemSQL1 Tables Add kbmMemTable1
kbmMemSQL1 ExecSQL
'StringField1'
'StringField2'
'NumberField1'
'NumberField2'
'String 1' 'AnotherString 1'
'String 2' 'AnotherString 1'
'String 3' 'AnotherString 1'
'String 4' 'AnotherString 2'
'String 5' 'AnotherString 2'
'String 6' 'AnotherString 2'
'String 7' 'AnotherString 3'
'String 8' 'AnotherString 3'
'String 9' 'AnotherString 3'
'table1'
'select * from table1'
The following samples are based on kbmSQL v. 1.01.00
Figure 1.
Figure 2.
expertstarter DELPHI 7 and above (Win32)LAZARUS
72 COMPONENTSDEVELOPERS 4 SEPTEMBER 2011 BLAISE PASCAL MAGAZINE 18
By running this simple application and clicking the button, we quickly have our first kbmSQL result returned… namely the same records that were contained in the kbmMemTable data source. Result:
Notice that kbmSQL operates with case insensitive field/table names, and thus the field names are uppercase by default.Let’s play a little with the different syntaxes kbmSQL supports. Change the SQL code in the ExecSQL call to try them out, one by one. Remember to escape (duplicate) single quotes (') when used in strings in Delphi. You can also use double quotes (“) which do not need to be escaped (duplicated) in Delphi strings.
I've already shown the SQL syntax for how to get data from all fields and all records. See above.
Specific fields:
Result:
select StringField1,NumberField2 from table1
Field alias with descriptive text:
Result:
select StringField2 as MyField (“My string field”), NumberField2 as Numbers from table1
Calculations and string concatenation:
Result:
select StringField2+” Some text” as MyField, NumberField2 / 2 as Numbers from table1
Sorting ascending:
Result: select * from table1 order by NumberField1
Sorting descending:
Result:
select * from table1 order by NumberField1 desc
Figure 3.
Figure 4.
Figure 5.
Filtering:
Result:
select * from table1 where NumberField1<30 and NumberField2>15
Figure 6.
Figure 7.
Figure 8.
Figure 9.
Structured Query Language for your memory table (Continuation 1)
SEPTEMBER 2011 BLAISE PASCAL MAGAZINE 18 73COMPONENTSDEVELOPERS 4
Statistical functions:
Result:
select count(*), min(NumberField1), max(NumberField1),avg(NumberField1), sum(NumberField1) from table1
Grouping:
Result:
select NumberField2, count(NumberField2), sum(NumberField1) from table1 group by NumberField2
Inserting new data using SQL:
Result (in raw data source):
insert into table1 (StringField1,StringField2, NumberField1,NumberField2) values (“New String1”,”New string2”,88.2,383)
Changing data using SQL:
Result (in raw data source):
update table1 set NumberField1= NumberField1 + 100 where NumberField2<20
Deleting data using SQL:
Result (in raw data source): delete from table1 where NumberField2<20
In addition kbmSQL supports filtering using between and in keywords. Eg.
Result:
select NumberField2 from table1 where NumberField1 between 10 and 20
And
Result:
select StringField1 from table1 where NumberField1 in (15,99,33)
And the SQL LIKE operator is also supported. LIKE matches string masks using * and ? as wildcards. * matches any number of arbitrary characters and ? matches exactly one arbitrary character. Eg.
Result:
select * from table1 where StringField1 like “*6*”
kbmSQL also contains a large predefined set of functions that can be used in expressions. To use them, you need to add kbmSQLStdFunc to the uses clause of the application. The functions include: COS(n), TAN(n), LOG(n), LOG2(n), TRUNC(n), MOD(n1,n2), DIV(n1,n2), SQR(n), UPPER(s), LOWER(s), TRIM(s), NOW, DATE(n), TIME(n), YEAR(n), MONTH(n), DAY(n), HOURS(n), MINUTES(n) and SECONDS(n).
Figure 10.
Figure 11
Figure 12.
Figure 13.
Structured Query Language for your memory table (Continuation 2)
Figure 14.
Figure 15.
Figure 16.
Figure 17.
SEPTEMBER 2011 BLAISE PASCAL MAGAZINE 1874 COMPONENTSDEVELOPERS 4
Notice that the default field name is now generated as F1. You can of course redefine the name using the AS syntax as shown earlier on. If you would like to use an expression function that is currently not available in kbmSQL it’s very easy to extend kbmSQL with new functionality.Let’s say we want to define a function that calculates
:
Then we create a new unit and add it to the project. Let’s call it myfunctions.pas.
Put the following into it:
Pythagoras' hypotenuse value
PYTHAGORAS(x,y) = sqr(x*x+y*y)
interface
uses
implementation
procedure constconst
beginif thenraise
end
function
varvar
begin2
ifthen
begin01
endelse
0
end
initialization
end
, , , , , ;
( : ; : );
. <>
. (+ ( ));
;
( : ; : ;
: ; : ): ;
, : ;
( , ); =
:= . [ ]. ; := . [ ]. ; := ( * + * ); := . [ ]. ; := ;
;
. ( ,@ , );
.
DB kbmSQLElements kbmSQLFuncAPIMath Classes SysUtils
CheckArgs AArgs TkbmSQLNodesACnt integer
AArgs Count ACnt
Exception Createinttostr ACnt
SQLPythagoras ASender TObjectAOperation TkbmSQLFunctionOperationAArgs TkbmSQLNodes AResult variant boolean
d1 d2 double
CheckArgs AArgsAOperation foExecute
d1 AArgs Node Executed2 AArgs Node ExecuteAResult sqrt d1 d1 d2 d2
AResult AArgs Node Width
Result true
kbmSQLFunctionRegistrations RegisterFunctionSQLPythagoras ftFloat
'Invalid number of arguments. Expected '
'PYTHAGORAS'
// Let it take width after first argument for function.
Basically what we do in the code, is to define our function, check that the correct arguments are available, produce the results that are to be used as arguments (d1 and d2) to our calculation and calculate a result.In addition the function contains functionality to tell kbmSQL about the resulting field width size, when kbmSQL needs to get that information.In the initialization section, we register the new function, and all that's needed for that function to be available for your SQL, is to include the unit in your main application’s uses clause.Eg.
Result:
select COS(NumberField1), Pythagoras(10,20) from table1
Obviously we could have used other field values or expressions instead of the constant values 10 and 20, used as arguments for Pythagoras.
All the above examples can be mixed and matched as required to perform complex searches and calculations on a single table. Currently kbmSQL does not support joins or HAVING syntax, but that's expected to be provided later on.
Eg.
Result: select COS(NumberField1) from table1
Structured Query Language for your memory table (Continuation 3)
Figure 18.
Figure 19.
SEPTEMBER 2011 BLAISE PASCAL MAGAZINE 18 75COMPONENTSDEVELOPERS 4
To receive a copy of the printed magazine you need to order a subscription from our website:www.blaisepascal.eu