Summary: in this tutorial, you will learn about SQLite STRICT
tables and their important features such as static typing columns.
Introduction to SQLite strict tables
In SQLite, ordinary tables use dynamic typing for columns. This means that the data types of the columns serve as hints rather than strict rules. Consequently, you can store values of any type in columns without strictly adhering to the declared data types.
For example, even if you declare a column with the INTEGER
type, you still can store a value of TEXT
or BLOB
type in that column.
This feature is unique to SQLite, but some developers find it challenging to work with. Therefore, SQLite introduced a strict typing mode for each table in SQLite 3.37.0
, released on Nov 27, 2021.
When creating tables, you have the option to enable the strict typing mode for each table separately by using the STRICT
keyword:
CREATE TABLE strict_table_name(
column type constraint,
...
) STRICT;
Code language: SQL (Structured Query Language) (sql)
These tables are often referred to as strict tables.
The strict tables follow these rules:
- Every column must have one of the following data types:
INT
,INTEGER
,REAL
,TEXT
,BLOB
, andANY
. - When inserting a value into a column, SQLite will attempt to convert the value into the column’s data type. If the conversion fails, it will raise an error.
- Columns with the
ANY
data type can accept any kind of data. SQLite will not perform any conversion for these columns. PRIMARY
KEY
columns are implicitlyNOT NULL
.- The
PRAGMA
integrity_check
andPRAGMA
quick_check
commands verify the type of the contents of all columns in strict tables and display errors if any mismatches are found.
SQLite strict table examples
Let’s take some examples using strict tables.
1) Basic SQLite strict table example
First, create a strict table called products
to store the product data:
CREATE TABLE products(
id INT PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL DEFAULT 0
) STRICT;
Code language: SQL (Structured Query Language) (sql)
The STRICT
keyword after the closing parenthesis )
indicates that the products
table is strict.
Second, attempt to insert NULL
into the id
column:
INSERT INTO products(id, name, price)
VALUES(NULL, 'A', 9.99);
Code language: SQL (Structured Query Language) (sql)
SQLite issues the following error:
SQL Error (19): NOT NULL constraint failed: products.id
Code language: SQL (Structured Query Language) (sql)
The reason is that the primary key column of a strict table implicitly has the NOT NULL
constraint. To make it work, you must provide a valid value for the id
column in the INSERT
statement.
Third, insert a new row into the products
table by providing values for all columns:
INSERT INTO products(id, name, price)
VALUES(1, 'A', 9.99);
Code language: SQL (Structured Query Language) (sql)
Alternatively, you can use the auto-increment column by changing the type of the id
column to INTEGER PRIMARY KEY
.
Fourth, recreate the products
table with the type of id column is INTEGER PRIMARY KEY
:
DROP TABLE IF EXISTS products;
CREATE TABLE products(
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL DEFAULT 0
) STRICT;
Code language: SQL (Structured Query Language) (sql)
In this case, if you insert NULL
into the id column, SQLite will use the next integer value for insertion.
Fifth, insert two rows into the products
table whose values in the id column are NULLs
:
INSERT INTO products(id, name, price)
VALUES(NULL, 'A', 9.99);
INSERT INTO products(id, name, price)
VALUES(NULL, 'B', 10.99);
Code language: SQL (Structured Query Language) (sql)
Sixth, retrieve data from products
table:
SELECT * FROM products;
Code language: SQL (Structured Query Language) (sql)
Output:
id | name | price
---+------+--------
1 | A | 9.99
2 | B | 10.99
(2 rows)
Code language: SQL (Structured Query Language) (sql)
The output indicates that SQLite uses the integers 1 and 2 for the insertion.
Seventh, insert a new row into the products table without providing the value for the id column:
INSERT INTO products(name, price)
VALUES('C', 5.59);
Code language: SQL (Structured Query Language) (sql)
Eighth, query data from products
table again:
SELECT * FROM products;
Code language: SQL (Structured Query Language) (sql)
Output:
id | name | price
---+------+-------
1 | A | 9.99
2 | B | 10.99
3 | C | 5.59
(3 rows)
Code language: SQL (Structured Query Language) (sql)
In this example, SQLite uses the next integer in the sequence and inserts it into the id column.
2) Converting data in strict tables
The following example demonstrates how SQLite attempts to convert input data into column data for insertion.
First, attempt to insert a new row into the products
table but the price is a text ‘4.99
‘:
INSERT INTO products(name, price)
VALUES('D', '4.49');
Code language: SQL (Structured Query Language) (sql)
SQLite will convert the text ‘4.49
‘ into a real number and insert it into the price column.
Second, retrieve data from the products
table:
SELECT * FROM products;
Code language: SQL (Structured Query Language) (sql)
Output:
id | name | price
---+------+------
1 | A | 9.99
2 | B | 10.99
3 | C | 5.59
4 | D | 4.49
(4 rows)
Code language: SQL (Structured Query Language) (sql)
Third, attempt to insert a new row into the products table but the price is a text ‘O.99
‘ with the first character is O
, not zero:
INSERT INTO products(name, price)
VALUES('E', 'O.99');
Code language: SQL (Structured Query Language) (sql)
In this case, SQLite cannot convert the ‘O.99
‘ into a real number, therefore, it issues the following error and aborts the insert:
Error: cannot store TEXT value in REAL column products.price
Code language: SQL (Structured Query Language) (sql)
3) Strict table vs ordinary table with ANY type
In a strict table, SQLite preserves the input data and does not carry any conversion. For example:
CREATE TABLE t1(c ANY) STRICT;
INSERT INTO t1(c) VALUES('0001');
SELECT c, TYPEOF(c) FROM t1;
Code language: SQL (Structured Query Language) (sql)
Output:
c | TYPEOF(c)
-----+-----------
0001 | text
(1 row)
Code language: SQL (Structured Query Language) (sql)
In this example, SQLite inserts the string ‘0001’ into the c column of the t table without any conversion.
However, in the ordinary table, SQLite attempts to convert a string that looks like a number into a numeric value and store it rather than the original string. For example:
CREATE TABLE t2(c ANY);
INSERT INTO t2(c) VALUES('0001');
SELECT c, TYPEOF(c) FROM t2;
Code language: SQL (Structured Query Language) (sql)
Output:
c | TYPEOF(c)
--+----------
1 | integer
(1 row)
Code language: SQL (Structured Query Language) (sql)
Summary
- Use the
STRICT
keyword to define strict tables. - Strict tables use static typing columns rather than dynamic typing columns.
- The
INTEGER
PRIMARY
KEY
column in strict tables has implicitNOT NULL
constraints.