SQLite Is Dynamically Typed - create table t1 (v1 int, v2 varchar(10)); sqlite> insert into t1 values ("abc", "this string is longer than 10 characters!"); sqlite> select * from t1; abc|this string is longer than 10 characters! sqlite> select typeof(v1), typeof(v2) from t1; text|text The null type is still special:'> create table t1 (v1 int, v2 varchar(10)); sqlite> insert into t1 values ("abc", "this string is longer than 10 characters!"); sqlite> select * from t1; abc|this string is longer than 10 characters! sqlite> select typeof(v1), typeof(v2) from t1; text|text The null type is still special:'> create table t1 (v1 int, v2 varchar(10)); sqlite> insert into t1 values ("abc", "this string is longer than 10 characters!"); sqlite> select * from t1; abc|this string is longer than 10 characters! sqlite> select typeof(v1), typeof(v2) from t1; text|text The null type is still special:'> create table t1 (v1 int, v2 varchar(10)); sqlite> insert into t1 values ("abc", "this string is longer than 10 characters!"); sqlite> select * from t1; abc|this string is longer than 10 characters! sqlite> select typeof(v1), typeof(v2) from t1; text|text The null type is still special:'><br>A small, cool fact about SQLite is that its columns are flexibly typed. You can<br>store any value in any column! Try it out:<br>sqlite> create table t1 (v1 int, v2 varchar(10));<br>sqlite> insert into t1 values ("abc", "this string is longer than 10 characters!");<br>sqlite> select * from t1;<br>abc|this string is longer than 10 characters!<br>sqlite> select typeof(v1), typeof(v2) from t1;<br>text|text<br>The null type is still special:<br>sqlite> create table t1 (v1 int, v2 varchar(10) NOT NULL);<br>sqlite> insert into t1 values ("abc", NULL);<br>Error: NOT NULL constraint failed: t1.v2<br>The longer story is that column definitions express a “type affinity” and SQLite<br>will try to do implicit conversions to match type affinity e.g. converting<br>strings of numeric characters to integers:<br>sqlite> insert into t1 values("123", "");<br>sqlite> select typeof(v1) from t1;<br>integer<br>Lots of databases support the type conversion behavior, but SQLite can’t do the<br>conversion it powers through and writes the bytes anyways.<br>I’d be curious to hear more about how this type system came to be. It seems<br>trickier to implement, but potentially useful? And also potentially<br>anti-useful? Are there users who totally eschew column types and actually rely<br>on this behavior for correctness?<br>As always, the insanely great SQLite docs have a lot more<br>detail.