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

Dimension Portable starting point Common divergence
Identifiers lowercase unquoted names; avoid reserved words Case folding, maximum length, quoting with double quotes/backticks/brackets
Generated keys standard identity concepts where available INTEGER PRIMARY KEY, SERIAL/IDENTITY, AUTO_INCREMENT, sequences
Boolean values BOOLEAN intent Native Boolean, integer 0/1, BIT, truthy expressions
Date/time typed timestamps and explicit time-zone policy Function names, interval syntax, storage precision, offset handling
Pagination ORDER BY plus standard OFFSET/FETCH where supported LIMIT/OFFSET, TOP, FETCH FIRST; optimizer and tie behavior
Upsert separate existence decision or adapter ON CONFLICT, ON DUPLICATE KEY UPDATE, MERGE
Returned rows follow-up SELECT in portable code RETURNING, OUTPUT, driver generated-key APIs
JSON store only when shape is genuinely semi-structured JSON/JSONB types, path syntax, indexes, functions
DDL small additive changes Implicit 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

Task SQLite PostgreSQL MySQL SQL Server Oracle
First 10 rows LIMIT 10 LIMIT 10 or FETCH FIRST LIMIT 10 TOP (10) or OFFSET/FETCH FETCH FIRST 10 ROWS ONLY
String combine a || b a || b or concat concat(a,b) a + b or concat a || b
Case-insensitive match LIKE depends on settings/collation ILIKE collation-dependent LIKE collation-dependent LIKE collation-dependent comparison
Upsert ON CONFLICT ON CONFLICT ON DUPLICATE KEY UPDATE MERGE MERGE
Return changed rows RETURNING RETURNING driver/follow-up SELECT OUTPUT RETURNING 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

Strategy Best fit Cost
Lowest common denominator Small application supporting several engines equally Leaves useful engine features unused
Dialect adapters A stable domain with a few known syntax differences Requires explicit interfaces and multi-engine tests
SQL toolkit/compiler Programmatic query composition across engines Generated SQL must still be inspected and tested
Vendor-first design Performance-sensitive or feature-rich platform Migration to another engine becomes a separate project
Read/write split by contract Portable writes, engine-specific analytics More 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.