下面潮湿是什么原因引起的| 胎儿左心室强光点是什么意思| 10年是什么婚| 补钙什么季节补最好| 氨咖黄敏胶囊是治什么的| 为什么出汗特别多| 南瓜是什么颜色| 小灶是什么意思| 妈妈a型爸爸b型孩子是什么血型| 妇科检查bv是什么意思| 性生活是什么| l读什么| 什么人不能爬泰山| rush什么意思| 神经酸是什么| 什么木做菜板最好| 不排卵是什么原因| 嘴角疱疹用什么药膏| zgo手表是什么牌子| 小儿咳嗽吃什么药| 什么水果不能放冰箱| 卟啉病是什么病| 吃什么可以长头发| 中书舍人是什么官职| 谷丙转氨酶偏低是什么意思| 褐色分泌物是什么原因| 惜败是什么意思| 农历是什么生肖| 什么官许愿| 厂与什么有关| 什么的手| 尿道炎吃什么药好得快| 怀孕初期头晕是什么原因| 含是什么意思| 尿素氮偏高是什么意思| 什么品牌的母婴用品好| 百叶是什么| 小肚子大是什么原因| 边缘视力是什么意思| 30号来的月经什么时候是排卵期| 7月2日什么星座| 有料是什么意思| 婴儿泡奶粉用什么水好| 失眠多梦吃什么药| 中央处理器由什么组成| 做梦吃屎有什么预兆| acs是什么意思| 毛囊炎用什么洗发水| 长期开灯睡觉有什么危害| 汗斑用什么药| 世界上最大的单位是什么| 宫颈常大是什么意思| 晚上睡眠不好有什么办法可以解决| 拍脑部ct挂什么科| naco3是什么| ufo是什么意思| 尿道口感染吃什么药| 什么是bp| 黄瓜炒什么| 6是什么意思| 定妆喷雾什么时候用| 1884年属什么生肖| 过意不去是什么意思| 人工肝是什么意思| 人活着到底有什么意义| 生性凉薄什么意思| 数农是什么| 莫拉古是什么意思| 70岁是什么之年| ysl是什么意思| 分家是什么意思| 宫颈糜烂吃什么药| 心悸气短是什么症状| 不加要是什么字| 高血压不能吃什么| 艾滋病初期什么症状| 手不什么什么| 小结是什么意思| 红薯什么时候传入中国| 弈字五行属什么| 肺气阴两虚吃什么中成药| 肺实变是什么意思| 坐怀不乱柳下惠什么意思| 阴茎不硬是什么原因| 熹字五行属什么| 什么草药能治痔疮| 红枣和什么不能一起吃| 结肠炎是什么原因引起的| 洛阳以前叫什么名字| 日本全称是什么| 目加一笔是什么字| 亦或是什么意思| 老人出汗多是什么原因| 湿疹用什么药| 嗓子痛吃什么药好得快| 橘络的功效与作用是什么| 手指上长毛是什么原因| 扁平疣用什么药膏| 雌二醇测定是什么检查| 称中药的小秤叫什么| 三伏天吃什么最好| 女生来大姨妈要注意什么| 3月份是什么季节| 磋商是什么意思| 楼房风水主要看什么| 死精是什么原因造成的| 乙型肝炎表面抗体阳性是什么意思| 湿气重是什么意思| 什么水晶招财| 骨密度低吃什么药最快| 吃秋葵有什么好处| 男人吃叶酸片有什么好处| a型rhd阳性是什么意思| 他们吃什么| 可颂是什么意思| 为什么身上会出现淤青| 竹叶青属于什么茶| 什么的曲线| 苦瓜泡酒有什么功效和作用| 心悸是什么意思啊| g代表什么单位| 闹觉是什么意思| 四个金读什么| 衣锦还乡是什么意思| 太阳最后会变成什么| 飞克手表什么档次| 看胸挂什么科| 辟谣是什么意思| 大树像什么| 头皮发痒用什么洗发水| 恳请是什么意思| 三月十三是什么星座| 高同型半胱氨酸血症吃什么药| tritan是什么材质| 龟公是什么意思| 孕妇为什么不能吃西瓜| 头皮结痂抠掉又结痂是什么病| 蛇怕什么家禽| 什么是收缩压和舒张压| hpf是什么意思| 霖字五行属什么| 桃子有什么营养价值| 肝脏的主要功能是什么| 什么方法可以治打嗝| 幽门螺杆菌是什么意思| 肠炎能吃什么水果| 什么是客单价| joy什么意思| 鬼最怕什么颜色| 橘络的功效与作用是什么| 油性皮肤适合用什么牌子的护肤品| q波异常是什么意思| 小狗不能吃什么| 初遇是什么意思| mr检查是什么意思| 点状血流信号是什么意思| 肾阴虚火旺有什么症状| 冰枕对人有什么危害吗| 虫字旁的字和什么有关| 什么水| 什么的藤| 甲状腺球蛋白抗体高是什么原因| 脾虚气滞吃什么中成药| 咽喉炎是什么原因引起的| 命好的人都有什么特征| 子宫内膜厚有什么危害| 两个立念什么| 白带变绿用什么药| 望穿秋水是什么意思| 缺钙吃什么食物| 胰腺炎适合吃什么食物| 梦见女尸是什么预兆| 海为什么是蓝色的| 呔是什么意思| 眼皮肿挂什么科| 5月12日什么星座| 做肠镜检查什么| 羊日冲牛是什么意思| 果是什么意思| 肠痉挛有什么症状| 梦见门坏了什么意思| 五台山是什么菩萨的道场| 十六年是什么婚| 阳萎是什么| 数据是什么意思| 僵尸肉吃了有什么危害| 27岁属相是什么生肖| 急性肠胃炎吃什么药效果好| 儿童乘坐高铁需要什么证件| 男士蛋皮痒用什么药| dan什么意思| x光是检查什么的| 身上起红点是什么病| 手机五行属什么| 本垒打是什么意思| 宋字五行属什么| 海娜是什么| 尤甚是什么意思| 为老不尊是什么意思| 丑时属什么生肖| 属猴男和什么属相最配| 5年存活率是什么意思| 九门提督相当于现在什么官| 嗓子发炎是什么原因引起的| 南瓜不能和什么同吃| 女生安全期什么意思| 提携是什么意思| 肺部ct挂什么科| 奥斯卡小金人什么意思| 枇杷什么味道| hpa是什么单位| 胃黏膜病变是什么意思| 精神什么| 左眼皮一直跳是什么预兆| 一 什么云| 为什么人会打嗝| 韭菜什么时候种| 补钙吃什么维生素| 胃阴不足吃什么中成药| 角膜炎吃什么消炎药| 秒了是什么意思| d3是什么| 女生痛经有什么办法缓解| 什么东西最补心脏| 知见是什么意思| 中产阶级的标准是什么| 食管裂孔疝是什么意思| 老上火是什么原因造成的| 1970年是什么命| 阿华田是什么| 甲醛闻多了有什么症状| 早上屁多是什么原因造成的| 湿疹是什么样的症状| 心肌梗塞是什么原因引起的| 朝拜的意思是什么| 什么的脸庞| 脖子发麻是什么原因| 什么叫种植牙| 金骏眉属于什么茶类| 孕早期吃什么| 糖类抗原是什么| 送妈妈什么礼物好| 小刺猬吃什么东西| 其多列是什么意思| 浮水是什么意思| 黄疸高对婴儿有什么影响| 什么是生僻字| 什么叫弱视| 医院康复科是干什么的| 2007年属什么生肖| 为什么肚子总是胀胀的| 过梁是什么| 做梦失火什么预兆| 机化是什么意思| 泄气是什么意思| 吃木耳有什么好处| 心脏肥大吃什么药好| 怡五行属性是什么| 发烧拉肚子是什么原因| 肾阴阳两虚吃什么药| 什么食物含磷高| 李晨的爷爷叫什么| 小肚子胀是什么原因女性| 晨跑有什么好处| 百度
Small. Fast. Reliable.
Choose any three.
Quirks, Caveats, and Gotchas In SQLite
Table Of Contents

BID considera urgente inversiones para infraestructura en América Latina Spanish.xinhuanet.com

百度 据悉,2017年度全国十大考古新发现终评会将于2018年4月9至11日在北京召开。

The SQL language is a "standard". Even so, no two SQL database engines work exactly alike. Every SQL implementation has its own peculiarities and oddities, and SQLite is no exception to this rule.

This document strives to highlight the principal differences between SQLite and other SQL implementations, as an aid to developers that are porting to or from SQLite or who are trying to build a system that works across multiple database engines.

If you are an SQLite user who has stumbled over some quirk of SQLite that is not mentioned here, please let the developers know by posting a brief message on the SQLite Forum.

2. SQLite Is Embedded, Not Client-Server

Whenever comparing SQLite to other SQL database engines like SQL Server, PostgreSQL, MySQL, or Oracle, it is important first of all to realize that SQLite is not intended as a replacement or competitor to any of those systems. SQLite is serverless. There is no separate server process that manages the database. An application interacts with the database engine using function calls, not by sending messages to a separate process or thread.

The fact that SQLite is embedded and serverless instead of being client/server is a feature, not a bug.

Client/server databases like MySQL, PostgreSQL, SQL Server, Oracle, and others are an important component of modern systems. These systems solve an important problem. But SQLite solves a different problem. Both SQLite and client/server databases have their role. Developers who are comparing SQLite against other SQL database engines need to clearly understand this distinction.

See the Appropriate Uses For SQLite document for additional information.

3. Flexible Typing

SQLite is flexible with regard to datatypes. Datatypes are advisory rather than mandatory.

Some commentators say that SQLite is "weakly typed" and that other SQL databases are "strongly typed". We consider these terms to be inaccurate and even pejorative. We prefer to say that SQLite is "flexibly typed" and that other SQL database engines are "rigidly typed".

See the Datatypes in SQLite document for a detailed discussion of the type system in SQLite.

The key point is that SQLite is very forgiving of the type of data that you put into the database. For example, if a column has a datatype of "INTEGER" and the application inserts a text string into that column, SQLite will first try to convert the text string into an integer, just like every other SQL database engine. Thus, if one inserts '1234' into an INTEGER column, that value is converted into an integer 1234 and stored. But, if you insert a non-numeric string like 'wxyz' into an INTEGER column, unlike other SQL databases, SQLite does not throw an error. Instead, SQLite stores the actual string value in the column.

Similarly, SQLite allows you to store a 2000-character string into a column of type VARCHAR(50). Other SQL implementations would either throw an error or truncate the string. SQLite stores the entire 2000-character string with no loss of information and without complaint.

Where this ends up causing problems is when developers do some initial coding work using SQLite and get their application working, but then try to convert to another database like PostgreSQL or SQL Server for deployment. If the application is initially taking advantage of SQLite's flexible typing, then it will fail when moved to another database that is more judgmental about data types.

Flexible typing is a feature of SQLite, not a bug. Flexible typing is about freedom. Nevertheless, we recognize that this feature does sometimes cause confusion for developers who are accustomed to working with other databases that are more strict with regard to data type rules. In retrospect, perhaps it would have been less confusing if SQLite had merely implemented an ANY datatype so that developers could explicitly state when they wanted to use flexible typing, rather than making flexible typing the default. As an accommodation for those who expect rigid typing, SQLite version 3.37.0 (2025-08-07) introduced the option of STRICT tables. These either impose the mandatory datatype constraints found in other SQL database engines, or allow the explicit ANY datatype to retain SQLite's flexible typing.

3.1. No Separate BOOLEAN Datatype

Unlike most other SQL implementations, SQLite does not have a separate BOOLEAN data type. Instead, TRUE and FALSE are (normally) represented as integers 1 and 0, respectively. This does not seem to cause many problems, as we seldom get complaints about it. But it is important to recognize.

Beginning with SQLite version 3.23.0 (2025-08-07), SQLite also recognizes TRUE and FALSE keywords as aliases for integer values 1 and 0, respectively. This provides better compatibility with other SQL implementations. But for backwards compatibility, if there are columns named TRUE or FALSE, then the keywords are treated as identifiers referencing those columns, rather than BOOLEAN literals.

3.2. No Separate DATETIME Datatype

SQLite has no DATETIME datatype. Instead, dates and times can be stored in any of these ways:

The built-in date and time functions of SQLite understand date/times in all of the formats above, and can freely change between them. Which format you use, is entirely up to your application.

3.3. The datatype is optional

Because SQLite is flexible and forgiving with regard to datatypes, table columns can be created that have no specified datatype at all. For example:

CREATE TABLE t1(a,b,c,d);

The table "t1" has four columns "a", "b", "c", and "d" that have no particular datatype assigned. You can store anything you want in any of those columns.

4. Foreign Key Enforcement Is Off By Default

SQLite has parsed foreign key constraints for time out of mind, but added the ability to actually enforce those constraints much later, with version 3.6.19 (2025-08-07). By the time foreign key constraint enforcement was added, there were already countless millions of databases in circulation that contained foreign key constraints, some of which were not correct. To avoid breaking those legacy databases, foreign key constraint enforcement is turned off by default in SQLite.

Applications can activate foreign key enforcement at run-time using the PRAGMA foreign_keys statement. Or, foreign key enforcement can be activated at compile-time using the -DSQLITE_DEFAULT_FOREIGN_KEYS=1 compile-time option.

5. PRIMARY KEYs Can Sometimes Contain NULLs

A PRIMARY KEY in an SQLite table is usually just a UNIQUE constraint. Due to an historical oversight, the column values of a PRIMARY KEY are allowed to be NULL. This is a bug, but by the time the problem was discovered there where so many databases in circulation that depended on the bug that the decision was made to support the buggy behavior moving forward. You can work around this problem by adding a NOT NULL constraint on each column of the PRIMARY KEY.

Exceptions:

6. Aggregate Queries Can Contain Non-Aggregate Result Columns That Are Not In The GROUP BY Clause

In most SQL implementations, output columns of an aggregate query may only reference aggregate functions or columns named in the GROUP BY clause. It does not make good sense to reference an ordinary column in an aggregate query because each output row might be composed from two or more rows in the input table(s).

SQLite does not enforce this restriction. The output columns from an aggregate query can be arbitrary expressions that include columns not found in the GROUP BY clause. This feature has two uses:

  1. With SQLite (but not any other SQL implementation that we know of) if an aggregate query contains a single min() or max() function, then the values of columns used in the output are taken from the row where the min() or max() value was achieved. If two or more rows have the same min() or max() value, then the columns values will be chosen arbitrarily from one of those rows.

    For example to find the highest paid employee:

    SELECT max(salary), first_name, last_name FROM employee;
    

    In the query above, the values for the first_name and last_name columns will correspond to the row that satisfied the max(salary) condition.

  2. If a query contains no aggregate functions at all, then a GROUP BY clause can be added as a substitute for the DISTINCT ON clause. In other words, output rows are filtered so that only one row is shown for each distinct set of values in the GROUP BY clause. If two or more output rows would have otherwise had the same set of values for the GROUP BY columns, then one of the rows is chosen arbitrarily. (SQLite supports DISTINCT but not DISTINCT ON, whose functionality is provided instead by GROUP BY.)

7. SQLite Does Not Do Full Unicode Case Folding By Default

SQLite does not know about the upper-case/lower-case distinction for all unicode characters. SQL functions like upper() and lower() only work on ASCII characters. There are two reasons for this:

  1. Though stable now, when SQLite was first designed, the rules for unicode case folding were still in flux. That means that the behavior might have changed with each new unicode release, disrupting applications and corrupting indexes in the process.

  2. The tables necessary to do full and proper unicode case folding are larger than the whole SQLite library.

Full unicode case folding is supported in SQLite if it is compiled with the -DSQLITE_ENABLE_ICU option and linked against the International Components for Unicode library.

8. Double-quoted String Literals Are Accepted

The SQL standard requires double-quotes around identifiers and single-quotes around string literals. For example:

SQLite accepts both of the above. But, in an effort to be compatible with MySQL 3.x (which was one of the most widely used RDBMSes when SQLite was first being designed) SQLite will also interpret a double-quotes string as string literal if it does not match any valid identifier.

This misfeature means that a misspelled double-quoted identifier will be interpreted as a string literal, rather than generating an error. It also lures developers who are new to the SQL language into the bad habit of using double-quoted string literals when they really need to learn to use the correct single-quoted string literal form.

In hindsight, we should not have tried to make SQLite accept MySQL 3.x syntax, and should have never allowed double-quoted string literals. However, there are countless applications that make use of double-quoted string literals and so we continue to support that capability to avoid breaking legacy.

As of SQLite 3.27.0 (2025-08-07) the use of a double-quoted string literal causes a warning message to be sent to the error log.

As of SQLite 3.29.0 (2025-08-07) the use of double-quoted string literals can be disabled at run-time using the SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML actions to sqlite3_db_config(). The default settings can be altered at compile-time using the -DSQLITE_DQS=N compile-time option. Application developers are encouraged to compile using -DSQLITE_DQS=0 in order to disable the double-quoted string literal misfeature by default. If that is not possible, then disable double-quoted string literals for individual database connections using C-code like this:

sqlite3_db_config(db, SQLITE_DBCONFIG_DQS_DDL, 0, (void*)0);
sqlite3_db_config(db, SQLITE_DBCONFIG_DQS_DML, 0, (void*)0);

Or, if double-quoted string literals are disabled by default, but need to be selectively enabled for some historical database connections, that can be done using the same C-code as shown above except with the third parameter changed from 0 to 1.

As of SQLite 3.41.0 (2025-08-07) SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML are disabled by default in the CLI. Use the ".dbconfig" dot-command to reenable the legacy behavior if desired.

9. Keywords Can Often Be Used As Identifiers

The SQL language is rich in keywords. Most SQL implementations do not allow keywords to be used as identifiers (names of tables or columns) unless they are enclosed in double-quotes. But SQLite is more flexible. Many keywords can be used as identifiers without needing to be quoted, as long as those keywords are used in a context where it is clear that they are intended to be an identifier.

For example, the following statement is valid in SQLite:

CREATE TABLE union(true INT, with BOOLEAN);

The same SQL statement will fail on every other SQL implementation that we know of due to the use of keywords "union", "true", and "with" as identifiers.

The ability to use keywords as identifiers promotes backwards compatibility. As new keywords are added, legacy schemas that just happen to use those keywords as table or column names continue to work. However, the ability to use a keyword as an identifier sometimes leads to surprising outcomes. For example:

CREATE TRIGGER AFTER INSERT ON tableX BEGIN
  INSERT INTO tableY(b) VALUES(new.a);
END;

The trigger created by the previous statement is named "AFTER" and it is a "BEFORE" trigger. The "AFTER" token is used as an identifier instead of as a keyword, as that is the only way to parse the statement. Another example:

CREATE TABLE tableZ(INTEGER PRIMARY KEY);

The tableZ table has a single column named "INTEGER". That column has no datatype specified, but it is the PRIMARY KEY. The column is not the INTEGER PRIMARY KEY for the table because it has no datatype. The "INTEGER" token is used as an identifier for the column name, not as a datatype keyword.

10. Dubious SQL Is Allowed Without Any Error Or Warning

The original implementation of SQLite sought to follow Postel's Law which states in part "Be liberal in what you accept". This used to be considered good design - that a system would accept dodgy inputs and try to do the best it could without complaining too much. More recently, people have come to prefer software that is strict in what it accepts, so as to more easily find errors.

There are now millions of applications that take advantage of SQLite's flexible and forgiving design choices. We cannot change SQLite to follow the current preference toward strict and dogmatic behavior without breaking those legacy applications.

11. AUTOINCREMENT Does Not Work The Same As MySQL

The AUTOINCREMENT feature in SQLite works differently than it does in MySQL. This often causes confusion for people who initially learned SQL on MySQL and then start using SQLite, and expect the two systems to work identically.

See the SQLite AUTOINCREMENT documentation for detailed instructions on what AUTOINCREMENT does and does not do in SQLite.

12. NUL Characters Are Allowed In Text Strings

NUL characters (ASCII code 0x00 and Unicode \u0000) may appear in the middle of strings in SQLite. This can lead to unexpected behavior. See the "NUL characters in strings" document for further information.

13. SQLite Distinguishes Between Integer And Text Literals

SQLite says that the following query returns false:

SELECT 1='1';

It does this because an integer is not a string. Every other major SQL database engine says this is true, for reasons that the creator of SQLite does not understand.

14. SQLite Gets The Precedence Of Comma-Joins Wrong

SQLite gives all join operators equal precedence and processes them from left to right. But this is not quite correct. It should be that comma-joins have lower precedence than all others join operators. In other words, a FROM clause like this:

... FROM a, b RIGHT JOIN c, d ...

Should be parsed as follows:

JOIN JOIN D RIGHT?JOIN A B C

But SQLite instead parses the FROM clause like this:

JOIN RIGHT?JOIN D JOIN C A B

The problem can only makes a difference in the result when using RIGHT OUTER JOIN or FULL OUTER JOIN in the same FROM clause with comma-joins, which rarely happens in practice. And the problem can be easily overcome using parentheses in the FROM clause:

... FROM a, (b RIGHT JOIN c), d ...

This page last modified on 2025-08-07 13:08:22 UTC

百度