The QUERY class is the kind of a query which can have a string representation in terms of SQL or, in other words, is an arbitrary SQL statement. Note, that in the further considerations, the term query means mainly this kind of a query.
The other argument in the "+" infix can be QUERY, STRING, INTEGER, REAL, DOUBLE, BOOLEAN or DATETIME. This is simple concatenation of value's string representation.
The "&" infix is smarter: there the other can be QUERY, STRING, CHARACTER, INTEGER, REAL, DOUBLE, BOOLEAN, DATETIME or ARRAY which contains objects of those types or Voids. It can also be FIELDS and, hence, RECORD. Finally, its type can be DB_TYPE.
Values of every presented data type should be converted to a string before merging. Rules for such merging are different and depend on the data type. For example, STRING and CHARACTER are enfoldered by quotes. The same happens with a QUERY. INTEGER, BOOLEAN, REAL and DOUBLE are converted to a string to be merged immediately. DATETIME is converted to a string and then is enfoldered by special symbol sequences to comly with the corresponding ODBC SQL extension syntax. The elements of ARRAY as well as FIELDS and RECORD are merged through a comma. Finally, DB_TYPE value is converted to a string containing DBMS-dependent type name, what's useful for such queries as CREATE TABLE, etc.
Note, that here and below a Void value is associated with Null in SQL. Therefore, to specify Null value you pass Void. As it will be shown below, the opposite is still true.
QUERY inherits not only SIMPLE_QUERY but also STRING class. It makes the process of creation very simple - you manipulate with QUERY exactly as it would be a string. There is, however, one important remark. Being created via the STRING's make or set, your query will not become attached until you make it. Therefore, to execute a query was made as a string you have either to attach it to a database via the attach feature or to profit by the execute_on:
database: DATABASE query: QUERY ... A. !!query.set("DELETE FROM COUNTRY WHERE NAME = 'USSR'") query.attach(database) query.execute B. !!query.set("DELETE FROM COUNTRY WHERE NAME = 'USSR'") query.execute_on(database)
You can also make use of the send feature for maximum simplicity:
!!query.send (database,"DELETE FROM COUNTRY")
The QUERY class not only makes the deferred class SIMPLE_QUERY effective for the case of SQL, but also extends it by two groups of features. The first group is comprised of SQL-oriented features giving the opportunity to execute query with parameters and prepare (precompile) query in the database if the repeated execution is expected. Features which belong to the second group offer a simple and visual way to construct queries from the parts having different data types. All those parts are added with automatic type conversion and enfoldering to comply with SQL grammar.
Combination of those features provides a simple and visual way to create effective queries with a high degree of reusability. For example , you may need to insert a lot of records into the PEOPLE table which contains such fields as id, name and birth_date. For this purpose you should execute the following SQL query:
INSERT INTO PEOPLE VALUES(_,_,_)
where the '_' sign denotes value of the corresponding field. Depending on your goals you can write either:
-- declare variables: query: QUERY -- query object id : INTEGER -- current value of id name : STRING -- current value of name bdate: DATETIME -- current value of birth_date ... -- assign values: id := 1 name := "Clint Westwood" !!bdate.make (1940, 5, 18, 10, 0, 0) !!query.set ("INSERT INTO PEOPLE VALUES(") query := query &, id &, name &, bdate + ')'
As a result you get a query with the current values embedded into the body of SQL statement. However, if you want to execute the same query on the same database many times and performance is important, you can create a parametrized query once, prepare it and execute the same query passing new parameters. The example above can be written like this:
-- create parametrized query: !!query.set ("INSERT INTO PEOPLE VALUES({id, name, bdate}") -- prepare query on the given database: query.prepare_on (database) -- set parameters: query.parameters.put (1, "id") query.parameters.put ("Kate Margaritova", "name") query.parameters.put ("1965-01-31 10:00:00", "bdate") -- execute query: query.execute -- again set parameters: query.parameters.put (2, "id") query.parameters.put ("Bingo Starr", "name") query.parameters.put ("1931-12-13 11:00:00", "bdate") -- again execute query: query.execute
...and so on.
See the PARAMETERS class for more explanation. See also the QUERY_COMPOSER class below to find out how to create queries even simpler that in those examples above.