Skip to content

SQL Lite in Forms

How SQLite is used in Versaa forms — device-local reference databases, how to build queries, and the builder+parser pattern.


What SQL Lite Is

Versaa forms can use SQLite databases (.db3 files) stored on the device as local reference data. This allows forms to: - Perform fast lookups without hitting the QL server on every interaction - Load complex classification data (ratings, CRM class levels) from a local source - Reduce strain on the SQL Server backend

SQLite databases are distributed to devices as Platform Files in Management Studio (Workflows → Variables → Platform Files → Reference Data). Developers download the .db3 file locally, edit it with DB Browser for SQLite (https://sqlitebrowser.org/), and re-upload.


Common Use Case — Awaabs Law Form

The Awaabs Law form moved classification data from QL to a local SQLite database (AwaabsOptions.db3). The database contains:

Tables

AnswerOptionList — Options with ratings and CRM classifications: | Column | Type | Purpose | |---|---|---| | aId | Integer | Primary key | | aOptionGroup | Integer | Groups related options | | qOptionNo | Integer | Display order | | qOptionText | Text | The display label shown in form | | qRating | Integer | Numeric risk rating | | qCRM1_Class_Level_1 through qCRM1_Class_Level_5 | Text | CRM classification values |

Questions — Question definitions: | Column | Purpose | |---|---| | qNo | Question identifier | | qQuestion | Question text | | qOverrideRating | Default override rating | | qAnswerOptionListGroup | Links to AnswerOptionList.aOptionGroup |

QuestionAnswers — Selected answer records: | Column | Purpose | |---|---| | qNo | Question number | | qAnswer | The selected answer text | | qRating | Rating of selected answer | | qOverrideRating | Override rating if set |


Critical Rule — Column Names Must Be [name] and [value]

SQLite query results must output exactly two columns named name and value (lowercase, exact). The Versaa form engine reads these two columns only. Any other column naming causes silent failures.

-- CORRECT
SELECT qOptionText AS name, qRating AS value FROM AnswerOptionList

-- WRONG — will not work
SELECT qOptionText AS label, qRating AS rating FROM AnswerOptionList

Builder + Parser Pattern

A powerful pattern for loading complex multi-value data into a form from a single SQLite query:

Step 1 — Build a pipe-delimited value in the SQL query:

SELECT
  qOptionText AS name,
  CAST(qRating AS TEXT) || '|' ||
  IFNULL(qCRM1_Class_Level_1, '') || ',' ||
  IFNULL(qCRM1_Class_Level_2, '') || ',' ||
  IFNULL(qCRM1_Class_Level_3, '') || ',' ||
  IFNULL(qCRM1_Class_Level_4, '') || ',' ||
  IFNULL(qCRM1_Class_Level_5, '') AS value
FROM AnswerOptionList
WHERE aOptionGroup = 3
ORDER BY qRating

Step 2 — Parse in form formulas using split():

// Get the rating (first pipe segment)
($formItem.z_SelectedValue.split("|")[0])

// Get CRM Class Level 1 (second pipe segment, then first comma segment)
($formItem.z_SelectedValue.split("|")[1].split(",")[0])

// Get CRM Class Level 2
($formItem.z_SelectedValue.split("|")[1].split(",")[1])

This pattern lets a single form item selection automatically populate rating and all five CRM classification levels.


Default Value Behaviour

When a SQLite lookup returns multiple rows, setting Filter = 1 returns only the first matching row. The value column is used as the pre-selected default (not name). Use this to pre-populate fields.


Stacked Queries

Queries can be chained — the output of one query becomes the filter input for the next. This enables complex lookups without additional back-end tables.


Getting the Tool

DB Browser for SQLite: https://sqlitebrowser.org/

Use this to: - Inspect an existing .db3 schema - Write and test queries before putting them into form providers - Add/edit data in the database before uploading to Management Studio