WitSQL is the SQL WitDatabase accepts. This section is the reference for it, and it is the only place on this site that explains syntax; everything else links here.
What it covers
| Area | Statements |
|---|---|
| Types | The type system, aliases, and what a value becomes at runtime |
| DDL | CREATE, ALTER and DROP for tables, indexes, views, triggers and sequences |
| DML | INSERT, UPDATE, DELETE, MERGE, RETURNING |
| Queries | SELECT, joins, CTEs, window functions, set operations |
| Functions | Strings, numbers, dates, JSON, aggregates and the rest |
| Routines | CREATE FUNCTION, CREATE PROCEDURE, CALL |
| Transactions | BEGIN, COMMIT, savepoints, isolation, locking hints |
| Compatibility | Where the dialect differs from the servers it stands in for |
| INFORMATION_SCHEMA | Reading a schema with SQL |
The shape of the dialect
The spelling follows SQLite, because that is the spelling most .NET developers have seen in an embedded database, and because it keeps a query portable between the two.
The coverage aims somewhere else. WitDatabase exists to stand in for a full database server, so
the question this dialect has to answer is whether a statement written for one keeps working here.
That is why stored procedures, user-defined functions, MERGE, window functions, INFORMATION_SCHEMA
and five isolation levels are present in an embedded engine, none of which the comparison with
SQLite would have called for.
Differences are found by running the same statements against real servers and comparing the answers, rather than by reading a specification. What that turns up is on compatibility.
Conventions
Keywords are shown in upper case and are not case-sensitive. SELECT and select are the same.
Identifiers are case-insensitive and are matched that way, so Users and users name the same
table. Quote an identifier with double quotes or square brackets when it collides with a keyword:
SELECT "Text", [Order] FROM Messages;Some keywords cannot stand as bare column names, most of them type names, and quoting them works.
The set shrinks as each one is found: Key, Top, Apply, Lateral, Function, Procedure,
Call, Language, Returns and Return all parse as column names now, and ROWID and LEVEL
always did. See limitations.
Parameters come in five spellings, so a statement written for another database usually runs:
SELECT * FROM Users WHERE Id = @id; -- named, and what this documentation uses
SELECT * FROM Users WHERE Id = :id; -- named, colon
SELECT * FROM Users WHERE Id = $id; -- named, dollar
SELECT * FROM Users WHERE Id = ?; -- positional
SELECT * FROM Users WHERE Id = ?1; -- numberedStatements are separated by semicolons. Comments are -- to end of line and /* ... */ across
lines.
What is not here
No stored program flow: the body of a procedure is a sequence of statements, and there is no IF,
no WHILE and no local variables. See routines for what a routine body can
contain.
No schemas in the SQL Server sense. There is one namespace, and dbo.Users will not parse.
No spatial types, no full-text search.
Where to go next
- Types, the place to start if you are writing DDL
- Queries, if you are writing a select
- Compatibility, if you are porting from another database