quisp: sql database interface

quick server pages
| Manual page for sql(database)

## SQL database interface

The #sql directive provides a convenient interface for building and invoking SQL commands, and capturing the results.`` By default #sql points to SHSQL (which is bundled with QUISP).`` Interfaces to other databases are also possible.``

A number of #sql examples are provided below; see also the live demo on sourceforge.``

## #sql - #endsql

Issue an SQL command.`` The SQL command can be one or more lines in length.`` Script variables and directives such as `#if` may be embedded in order to conditionally build an SQL command.`` Command status is available via $sqlerror() (a nonzero value indicates an error).`` For `SELECT` commands, the number of retrieved rows is available via $sqlrowcount() and individual result rows are retrieved using $sqlrow().``

Usage:

       #sql [ichannel]  [mode]
          sql command
          ...
       #endsql

Alternatively, a single-line form may be used:
`#sql [`ichannel] [mode`]` sql command

ichannel is `1`, `2`, `3` or `4`. When ichannel is not specified channel 1 is assumed.`` The channel number may be preceded by a pound sign `#` if desired.`` Multiple channels are useful in nested contexts, eg. a retrieval on channel 1 is in progress, and a retrieval is being done (on channel 2) for every channel 1 result row.`` The database access functions below also accept a channel argument.`` See example 8 below which uses channels.``

mode may be one of the following:

  `processrows` - any result rows will be available via the `$sqlrow()` function. This is the default.``

  `load` - one result row is expected, and each result field will be loaded into an appropriately-named variable.``

  `dump` - write the results directly to standard output.

  `dumptab` - result lines are parsed into fields and written to standard output delimited by tabs.``

  `dumphtml` - result lines are parsed into fields and written to standard output as HTML table rows.``

  `dumpsilent` - don't display result lines at all, but row count will be available via `$sqlrowcount()`.``

Hint: In CGI mode, output some HTML (even if just `<br>`) before the `#sql` statement; this allows any error messages to be displayed in the browser.``

Note: mode may begin with a pound sign (`#`) if desired, for readability.``

Note: `#shell` directives cannot be embedded within `#sql` / `#endsql`.``

## #sqlblankrow

`#sqlblankrow` dbtable

For every field defined in database table dbtable, initialize a variable to `""`.`` This operator is useful when setting up a form for new content entry, where the form fields correspond to fields in a database table.``

## #sqlcgivars

Get an ordinary CGI user variable for every field defined for database table dbtable.`` Typical use is on a form target page; using `#sqlcgivars` lets you avoid having to enumerate all fields in a `#cgivar` statement.`` The CGI user variable names must exactly match the database table field names.``

Usage: `#sqlcgivars` dbtable `[overwrite]`

Example: `#sqlcgivars people`

Example: `#sqlcgivars people overwrite`

Unless the `overwrite` option is given, variables that are already in use (have already been given a value) will NOT be set by `#sqlcgivars`.``

If any of the variables need to be captured using special conversions (eg.`` `#cgilistvar`, `#cgitextvar`, or `#cgimultivar`), these operators must be invoked before `#sqlcgivars`, and the `overwrite` option must not be used.``

Caution: any fields not present in the submitted form must be passed to the target page using #pass; otherwise any existing contents of those fields will be lost.``

## #sqlbuild

Automatically builds an SQL `INSERT` command or most of an `UPDATE` command.`` Traditionally in systems where SQL is submitted by middleware, the SQL command is coded manually, like in the INSERT command in example 5 below, and the developer must manually enumerate all fields, as well as code for quoting, conversion of blank fields to NULL, and escape out any embedded quotes.``

If `#sqlbuild` is used, much of this work is done for you; see examples 6 and 7 below.`` For UPDATE, the developer must supply a trailing where clause as shown.`` `#sqlbuild` assumes that a script variable exists for each database field, and has the same name as the database field. `#sqlbuild` is typically used in a form target page where a data record has been submitted from a form, and where the fields have been loaded using #sqlcgivars.``

Usage: `#sqlbuild` umode dbtable defaultqmode [omit=fields] [noquote=fields] [quote=fields]

  umode is either `insert` or `update` (`new` is accepted as equivalent to `insert`).``

  dbtable is the name of the database table being updated.``

  defaultqmode is the default quoting mode, either `quote` or `noquote`. Unless listed in the exceptions, all fields are treated this way.``

  The `omit=` parameter (optional) names fields that shouldn't be included at all.``

  The `noquote=` parameter (optional) names fields that shouldn't be quoted, for when defaultqmode is `quote`.``

  The `quote=` parameter (optional) names fields that should be quoted, when defaultqmode is `noquote`.``

fields should be a comma-delimited list of fieldnames with no embedded whitespace.``

Here are the `#sqlbuild` conversion rules. Empty fields are converted to `null`.`` Fields that are to be quoted are enclosed in double quotes (`"`); if any embedded double quotes are found these are converted to single quotes (avoids embedded escape characters and works well with HTML form tags). An entry for every dbtable field is generated (except those mentioned if `omit=` is used) in logical table order.``

Hint: during development don't put the `#sqlbuild` within a `#sql` / `#endsql` right away; first put it within a `<pre>` / `</pre>` and just see the SQL that it builds.``

## Functions

These functions may be used in conjunction with the `#sql` command.`` Many of the functions take an argument `dbc` which specifies the database connection path, an integer between 1 and 4 (if omitted, `1` is assumed).``

$sqlrow( dbc )

  Get the next SQL result row.`` Result fields are loaded into variables that use the same names as the SQL result columns.`` NULL fields will be converted to "".`` Returns 0 on success, 1 if no more result lines, or an error code > 1.`` See example 3 below.``

$sqlrowcount( dbc )

  Return the number of result rows produced by the most recently invoked SQL command.``

$sqlpushrow( dbc )

  Causes the next call to `$sqlrow()` to get the same row again.``

$sqlerror( dbc )

  Returns the completion status of the most recently invoked SQL command.`` Zero indicates success; nonzero indicates an error.``
  Example: `#if $sqlerror() != 0 ...`

$sqltabdef( dbc, table )

  Returns a comma-delimited list of the field names in table. This requires its own free db channel (if used on same channel as a retrieval in progress it will intefere).`` Example:

        #set names = $sqltabdef( people )
        #set n_names = $count( "*", @names )

$sqlprefix( dbc, prefix )

  Set a prefix to be prepended to all result field names retrieved by the next SELECT command. This may be used to prevent result field names from colliding with existing script variable names.`` Must be used after the #sql statement and before `$sqlrow()`.`` The prefix remains in effect for the current query only.``
  Example: `#call $sqlprefix( "s" )`

$sqlstripprefix( dbc, prefix )

  Indicates that prefix should be removed from the beginning of any result field name where it appears, for example to remove table name prefix from join results.`` Must be used after the #sql statement, and before `$sqlrow()`.`` Remains in effect for the current query only.``
  Example: `#call $sqlstripprefix( "people." )`

$sqlwritable()

  Returns 0 if the current process can write to the database.`` Returns 1 if writes are prohibited because of config file readonly attribute.`` Returns 2 if writes cannot be done because of unix file or directory permissions issues.``

#mode nullrep

  You can control how database `null` fields are represented within scripts.`` By default they are represented as zero-length strings. Use `nbsp` to convert NULLs to the HTML non-breaking space character `&nbsp;` which is useful for avoiding dead table cells.``

  Note that #mode is not a function but rather a script operator, and should be invoked before result rows are fetched.``

## Examples

In `./qexamples` are a number of examples that do various things, see the README file there.``

Example 1. Invoke a simple SQL command and display the results:

       <pre>
       #sql #dump select * from classlist
       </pre>

       #if $sqlrowcount() != 0
        <h3>Nothing found</h3>
       #endif

Example 2. Similar to above but display results as HTML table rows:

       #set SEARCH = "gib"

       <table cellpadding=2>
       #sql #dumphtml select * from classlist where lastname like "@SEARCH*"
       </table>

       #if $sqlrowcount() != 0
        <h3>Nothing found</h3>
       #endif

Example 3. Process result rows one at a time:

        #set MINCORR = 0.7

        #sql
          select * from correlations
          where pearson > @MINCORR
        #endshell

        <table cellpadding=2>
        #while $sqlrow() == 0
          <tr><td>@var1</td><td>@var2</td><td>@pearson</td><td>N = @n</td></tr>
        #endloop
        </table>

        #if $sqlrowcount() < 1
          <h3>No correlations computed</h3>
        #endif

Example 4. Use an SQL command to load some variables:

        #set ID = 908
        #sql #load select lastname, firstname, email from people where id = @ID
        Name: @lastname, @firstname &nbsp; email: @email <br>

Example 5. Issue an SQL INSERT command, without using #sqlbuild:

        #sql
          insert into people (id, lastname, firstname, email )
          values ( @id, "@lastname", "@firstname", "@email", balancedue )
        #endsql

        #if $sqlerror() != 0
           <h3>An error occurred!</h3>
        #endif

Example 6. Issue an SQL INSERT command, using #sqlbuild to handle quoting, etc.:

        #sql
            #sqlbuild  insert  people  quote   noquote=id,balancedue
        #endsql

Example 7. Issue an SQL UPDATE command, using #sqlbuild to handle quoting, etc:

        #sql
          #sqlbuild  update  people  quote  omit=id  noquote=balancedue
          where id = 908
        #endsql

Example 8. Nested SQL SELECT commands using channels 1 and 2:

       #sql select caseid from cases order by caseid
       #while $sqlrow() = 0
          #sql #2 select details from casedetails where caseid = @caseid
          #while $sqlrow( 2 ) = 0
           ....
          #endloop
       #endloop

Example 8. A data entry form example
quick server pages
Copyright Steve Grubb

Markup created by unroff 1.0, `` `` April 13, 2004.