Chapter 17 · SQL Dialects, Tools, and Application Access

ANSI SQL and Major Vendor Dialects

SQL is a standardized language family implemented by products with different types, functions, syntax, limits, and operational behavior. Professional portability begins by separating relational intent from dialect-specific mechanisms and testing the exact engines you support.

Intermediate150–185 minutesStandards analysis + portability laboratoryLast reviewed: August 2026

Learning outcomes

Learning outcomes

01

Explain the relationship between ISO/IEC SQL standards and product dialects.

02

Identify portability risks in identifiers, types, functions, pagination, generated values, UPSERT, JSON, and DDL.

03

Write a conservative SQL baseline and isolate vendor-specific capabilities behind explicit boundaries.

04

Build capability probes that fail early on unsupported engines or versions.

05

Decide when portability is valuable and when a deliberate vendor commitment is justified.

One language family, many implementations

STD

Standard SQL

The standards define grammar, semantics, data types, modules, and optional features. They are specifications—not one executable product.

DIA

Dialect

A database engine implements a subset, adds extensions, and may assign different behavior to similar syntax.

DRV

Driver layer

Parameter markers, type conversion, generated-key retrieval, and transaction APIs can differ even when SQL text is identical.

OPS

Operational semantics

DDL transactions, locking, isolation defaults, identifier folding, and error behavior affect deployments beyond syntax.

Relational requirement
Portable SQL core
Capability boundary
Dialect adapter
Engine-specific test suite

Portability is an architecture and verification problem, not a search-and-replace exercise.

Portability dimensions

DimensionPortable starting pointCommon divergence
Identifierslowercase unquoted names; avoid reserved wordsCase folding, maximum length, quoting with double quotes/backticks/brackets
Generated keysstandard identity concepts where availableINTEGER PRIMARY KEY, SERIAL/IDENTITY, AUTO_INCREMENT, sequences
Boolean valuesBOOLEAN intentNative Boolean, integer 0/1, BIT, truthy expressions
Date/timetyped timestamps and explicit time-zone policyFunction names, interval syntax, storage precision, offset handling
PaginationORDER BY plus standard OFFSET/FETCH where supportedLIMIT/OFFSET, TOP, FETCH FIRST; optimizer and tie behavior
Upsertseparate existence decision or adapterON CONFLICT, ON DUPLICATE KEY UPDATE, MERGE
Returned rowsfollow-up SELECT in portable codeRETURNING, OUTPUT, driver generated-key APIs
JSONstore only when shape is genuinely semi-structuredJSON/JSONB types, path syntax, indexes, functions
DDLsmall additive changesImplicit commits, ALTER TABLE breadth, online options, transactional DDL

A conservative relational baseline

portable SQL · intent-first schema
CREATE TABLE customer (    customer_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,    email VARCHAR(320) NOT NULL UNIQUE,    display_name VARCHAR(200) NOT NULL,    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);SELECT customer_id, email, display_nameFROM customerWHERE created_at >= ?ORDER BY created_at, customer_idFETCH FIRST 100 ROWS ONLY;

The schema expresses intent with standard concepts, but the parameter marker and generated-identity syntax still need validation for each driver and engine.

Equivalent intent, different syntax

TaskSQLitePostgreSQLMySQLSQL ServerOracle
First 10 rowsLIMIT 10LIMIT 10 or FETCH FIRSTLIMIT 10TOP (10) or OFFSET/FETCHFETCH FIRST 10 ROWS ONLY
String combinea || ba || b or concatconcat(a,b)a + b or concata || b
Case-insensitive matchLIKE depends on settings/collationILIKEcollation-dependent LIKEcollation-dependent LIKEcollation-dependent comparison
UpsertON CONFLICTON CONFLICTON DUPLICATE KEY UPDATEMERGEMERGE
Return changed rowsRETURNINGRETURNINGdriver/follow-up SELECTOUTPUTRETURNING INTO

Capability probes

sql · feature probes
-- Run in an isolated scratch schema during certification.WITH probe(value) AS (VALUES (1))SELECT value FROM probe;CREATE TEMPORARY TABLE capability_probe (    id INTEGER PRIMARY KEY,    payload TEXT NOT NULL);INSERT INTO capability_probe(id,payload)VALUES (1,'first')ON CONFLICT(id) DO UPDATE SET payload=excluded.payloadRETURNING id,payload;DROP TABLE capability_probe;
text · capability manifest
engine: postgresqlminimum_version: 16required:  - recursive_cte  - window_functions  - transactional_ddl  - returningoptional:  - json_path  - generated_columnsunsupported_path: fail_startup

Probe behavior in CI against every supported engine version. Documentation review is necessary, but executable certification catches driver settings, compatibility modes, and cloud-service restrictions.

Portability strategies

StrategyBest fitCost
Lowest common denominatorSmall application supporting several engines equallyLeaves useful engine features unused
Dialect adaptersA stable domain with a few known syntax differencesRequires explicit interfaces and multi-engine tests
SQL toolkit/compilerProgrammatic query composition across enginesGenerated SQL must still be inspected and tested
Vendor-first designPerformance-sensitive or feature-rich platformMigration to another engine becomes a separate project
Read/write split by contractPortable writes, engine-specific analyticsMore code paths and operational ownership

SQLite laboratory

sqlite · baseline and dialect observations
PRAGMA foreign_keys = ON;DROP TABLE IF EXISTS order_item;DROP TABLE IF EXISTS sales_order;DROP TABLE IF EXISTS product;DROP TABLE IF EXISTS customer;CREATE TABLE customer (  customer_id INTEGER PRIMARY KEY,  email TEXT NOT NULL UNIQUE,  display_name TEXT NOT NULL,  region TEXT NOT NULL CHECK(region IN ('north','south','east','west')),  created_at TEXT NOT NULL) STRICT;CREATE TABLE product (  product_id INTEGER PRIMARY KEY,  sku TEXT NOT NULL UNIQUE,  product_name TEXT NOT NULL,  unit_price_cents INTEGER NOT NULL CHECK(unit_price_cents>=0),  active INTEGER NOT NULL DEFAULT 1 CHECK(active IN (0,1))) STRICT;CREATE TABLE sales_order (  order_id INTEGER PRIMARY KEY,  customer_id INTEGER NOT NULL REFERENCES customer(customer_id),  status TEXT NOT NULL CHECK(status IN ('draft','submitted','paid','cancelled')),  ordered_at TEXT NOT NULL,  request_key TEXT UNIQUE) STRICT;CREATE TABLE order_item (  order_id INTEGER NOT NULL REFERENCES sales_order(order_id) ON DELETE CASCADE,  product_id INTEGER NOT NULL REFERENCES product(product_id),  quantity INTEGER NOT NULL CHECK(quantity>0),  unit_price_cents INTEGER NOT NULL CHECK(unit_price_cents>=0),  PRIMARY KEY(order_id,product_id)) STRICT;INSERT INTO customer VALUES(1,'ada@example.com','Ada Lovelace','north','2026-01-10'),(2,'grace@example.com','Grace Hopper','east','2026-02-15'),(3,'linus@example.com','Linus Torvalds','west','2026-03-01');INSERT INTO product VALUES(10,'DB-BOOK','Database Design Handbook',4200,1),(11,'SQL-CARD','SQL Reference Cards',1800,1),(12,'ARCHIVE','Archived Product',9900,0);INSERT INTO sales_order VALUES(1001,1,'paid','2026-08-01 09:00:00','req-1001'),(1002,1,'submitted','2026-08-02 10:30:00','req-1002'),(1003,2,'draft','2026-08-03 14:15:00','req-1003');INSERT INTO order_item VALUES(1001,10,1,4200),(1001,11,2,1800),(1002,11,3,1800),(1003,10,1,4200);SELECT c.region, COUNT(*) AS customersFROM customer AS cGROUP BY c.regionORDER BY c.region;INSERT INTO product(product_id,sku,product_name,unit_price_cents)VALUES(11,'SQL-CARD','SQL Cards, revised',1900)ON CONFLICT(product_id) DO UPDATE SET  product_name=excluded.product_name,  unit_price_cents=excluded.unit_price_centsRETURNING product_id,sku,unit_price_cents;

Portability review

Review the design

  1. Why does valid SQL on one engine not prove portability?
  2. Why should identifiers be kept simple and unquoted when possible?
  3. When is vendor-specific SQL the better engineering choice?
  4. What belongs in a capability manifest?
Review the answers

The standard contains optional features and products add or reinterpret behavior. Simple names avoid case-folding and quoting traps. Vendor-specific SQL is appropriate when its value exceeds portability needs and the commitment is explicit. A manifest records engine/version constraints, required capabilities, optional capabilities, and the policy for unsupported environments.

Lesson summary

  • SQL standards provide a common model, not identical implementations.
  • Portability includes syntax, types, driver APIs, transactions, DDL, and operations.
  • Keep a conservative core, isolate extensions, and certify every supported engine.
  • Choose portability deliberately rather than accidentally limiting or coupling the system.

References

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.