docs.roxen.comView this page in a printer friendly mode
DocsRoxenWebServer 3.3TutorialsDatabase Tutorial
Copyright  2004, Roxen Internet Software
Suggestions, comments & compliments

Building a Sample Database
The query() function
The big_query() function
SQL Syntax
Features Missing from MySQL
Insertion Syntax
The tablify Container
The Business Graphics Module
The emit and sqlquery Tags
Database Creation
Creating Tables

SQL Syntax

The most basic SQL syntax for a data-extraction query is:

SELECT what FROM table name[, table name ...] [WHERE conditions]

what defines what you wish to get from the query. It can be a column name (more on column names later), a function to be performed on the retrieve data (more on this in the functions chapter). The special notation '*' means "all columns from all the specified tables".

In order to extract everything from a table, with RXML:

<sqltable border="1"
  query="SELECT * FROM boundaries">

with Pike:

 string parse (object id) {
    object db=Sql.sql("mysql://user:password@localhost/sample");
    array(mapping) results=db->query("select * from boundaries");
    string output="<table border=1>";
    foreach (results,mapping m) {
    return output;'

If we wanted to get the results only for a column in that table, we would have instead

with RXML:

<sqltable border="1"
  query="SELECT length FROM boundaries">

Of course you can select more than one column, simply having what be a comma-separated list of column names.

With RXML:

<sqltable border="1"
  query="SELECT country_1, country_2 FROM boundaries">

Using a single table doesn't harness the power of relations. Those are not "physical" entities, but are built when a query is executed if multiple tables are specified together with conditions to explain how the data from the tables should be collated (or "the tables are joined"). Usually an equality test is used to specify those conditions, but it's not a requirement. The result of the join operation is a virtual table merging those records from every involved table that satisfy the specified conditions.

Let's print the name of the known countries and the geographic regions they belong to. The country names are in the 'ids' table, the regions are in the 'areas' table, the two are tied via the 'countries' table. The relations we'll use are two: ids.code must be equal to, and countries.map_refs must be equal to

with RXML

<sqltable border="1"
  query="SELECT AS country, AS region
           FROM ids, countries, areas

Column Names

A column can be addressed in two ways: "plain" and "dotted notation". The latter is the more complete form, and is guaranteed not to be ambiguous. The former is allowed for brevity's sake by most servers (including MySQL), but only when no confusion is possible.

Aliases for Columns

It is possible (usually to have a function result with a simpler name) to alias the names of the returned columns, simply extending the what parameter above with the syntax

column_name AS alias

The values will be then available in the result as "alias" column, rather than "column_name".

With RXML:

<sqltable border="1"
  query="SELECT country_1 AS first_country,
                country_2 AS second_country FROM boundaries">

See the functions chapter to see how for an example when using functions.

Aliases for Tables

Table names can be aliased with the "as" syntax, too. This is especially important in one case, and that is when you need to cross-reference a table with itself, or if a table is involved in multiple relations with another. It's illegal in SQL to have two or more tables with the same name mentioned in the tables list of a query.

With our sample database, it's necessary to alias a table if we want to expand the country codes in the boundaries table to their names. In order to accomplish that result, we will need to:

With RXML:

<sqltable border="1"
  query="SELECT AS name_1,
       AS name_2, length
           FROM ids AS ids_1, ids AS ids_2, boundaries 
          WHERE ids_1.code=boundaries.country_1
            AND ids_2.code=boundaries.country_2">

Here we aliased two times the 'ids' table for clarity's sake, we could have aliased it only once. Also, we aliased the column names for the same reason.

No Tables Involved

It is possible to have queries which don't involve any table, simply by not specifying the "FROM" clause. Such queries are not very useful, except sometimes to perform server-assisted translations.

With Pike:

 > object db=Sql.sql("mysql://user:password@localhost/sample");
Result: object;
> db->query("select now() as time")[0]->time;
Result: "2000-02-29 12:12:57" 

The conditional part of a query is explained in the following chapter.