衡阳农村用热水炉:SQLite 不支持的 SQL 特性

来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 13:49:21
http://www.xuedelphi.cn/wenzhang/mrjq/jyjq/2010/01/201001143320.htm
2010-2-10 10:26:14

外键约束(FOREIGN KEY constraints)
外键约束会被解析但不会被执行。

完整的触发器支持(Complete trigger support)
现 在有一些触发器的支持,但是还不完整。 缺少的特性包括FOR EACH STATEMENT 触发器(现在所有的触发器都必须是 FOR EACH ROW ), 在表上的 INSTEAD OF触发器(现在 INSTEAD OF 触发器只允许在视图上), 以及递归触发器——触发自身的触发器。

完整的 ALTER TABLE 支持(Complete ALTER TABLE support)
只支持 ALTER TABLE 命令的 RENAME TABLE 和 ADD COLUMN。 其他类型的 ALTER TABLE 操作如 DROP COLUMN,ALTER COLUMN,ADD CONSTRAINT 等等均被忽略。

嵌套事务(Nested transactions)
现在的实现只允许单一活动事务。

RIGHT 和 FULL OUTER JOIN(RIGHT and FULL OUTER JOIN)
LEFT OUTER JOIN 已经实现,但还没有 RIGHT OUTER JOIN 和 FULL OUTER JOIN。

可写视图(Writing to VIEWs)
SQLite 中的视图是只读的。无法在一个视图上执行 DELETE,INSERT,UPDATE。 不过你可以创建一个试图在视图上 DELETE,INSERT,UPDATE 时触发的触发器,然后在触发器中完成你所需要的工作。

GRANT 和 REVOKE(GRANT and REVOKE)
由 于 SQLite 读和写的是一个普通的磁盘文件,因此唯一可以获取的权限就是操作系统的标准的文件访问权限。 一般在客户机/服务器架构的关系型数据库系统上能找到的 GRANT 和 REVOKE命令对于一个嵌入式的数据库引擎来说是没有意义的, 因此也就没有去实现。

SQLite不支持的SQL语法总结
1 TOP

这是一个大家经常问到的问题,例如在SQLSERVER中可以使用如下语句来取得记录集中的前十条记录:

SELECT TOP 10 * FROM [index] ORDER BY indexid DESC;

但是这条SQL语句在SQLite中是无法执行的,应该改为:

SELECT * FROM [index] ORDER BY indexid DESC limit 0,10;


其中limit 0,10表示从第0条记录开始,往后一共读取10条


2 创建视图(Create View)

SQLite在创建多表视图的时候有一个BUG,问题如下:

CREATE VIEW watch_single AS SELECT DISTINCT watch_item.[watchid],watch_item.[itemid] FROM watch_item;


上面这条SQL语句执行后会显示成功,但是实际上除了

SELECT COUNT(*) FROM [watch_single ] WHERE watch_ single.watchid = 1;

能执行之外是无法执行其他任何语句的。其原因在于建立视图的时候指定了字段所在的表名,而SQLite并不能正确地识别它。所以上面的创建语句要改为:

CREATE VIEW watch_single AS SELECT DISTINCT [watchid],[itemid] FROM watch_item;


但是随之而来的问题是如果是多表的视图,且表间有重名字段的时候该怎么办?


3 COUNT(DISTINCT column)

SQLite在执行如下语句的时候会报错:

SELECT COUNT(DISTINCT watchid) FROM [watch_item] WHERE watch_item.watchid = 1;

其原因是SQLite的所有内置函数都不支持DISTINCT限定,所以如果要统计不重复的记录数的时候会出现一些麻烦。比较可行的做法是先建立一个不重复的记录表的视图,然后再对该视图进行计数。


4 外连接

虽然SQLite官方已经声称LEFT OUTER JOIN 已经实现,但还没有 RIGHT OUTER JOIN 和 FULL OUTER JOIN。但是实际测试表明似乎并不能够正常的工作。以下三条语句在执行的时候均会报错:

SELECT tags.[tagid] FROM [tags],[tag_rss] WHERE tags.[tagid] = tag_rss.[tagid](*);

SELECT tags.[tagid] FROM [tags],[tag_rss] WHERE LEFT OUTER JOIN tag_rss.[tagid] = tags.[tagid];

SELECT tags.[tagid] FROM [tags],[tag_rss] WHERE LEFT JOIN tag_rss.[tagid] = tags.[tagid];


此外经过测试用 号代替*号也是不可行的。
sqlite和sql server语法上的一些区别
1. @@IDENTITY LAST_INSERT_ROWID()
2. SELECT cn = COUNT(*) FROM … SELECT COUNT(*) cn FROM …
3. LIMIT startIndex,itemCn 这儿的startIndex是从0开始的,而ROW_NUMBER()是从1开始的
4. sqlite中没有SELECT TOP,用LIMIT即可
5. SQLite自增字段,如果在事务中插入数据失败,并不会占用增长后的id,而sql server中对应的id将无效
6. SQLite中没有GETDATE日期函数
7. SQLite支持REPLACE INTO语法,sql server 2008中支持merge to


(#)