sqlite-sqlite3高级2
SQLite Truncate Table在 SQLite 中,并没有 TRUNCATE TABLE 命令,但可以使用 SQLite 的 DELETE 命令从已有的表中删除全部的数据,但建议使用 DROP TABLE 命令删除整个表,然后再重新创建一遍。 语法DELETE 命令的基本语法如下: sqlite> DELETE FROM table_name; DROP TABLE 的基本语法如下: sqlite> DROP TABLE table_name; 如果您使用 DELETE TABLE 命令删除所有记录,建议使用 VACUUM 命令清除未使用的空间。 实例假设 COMPANY 表有如下记录: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 下面为删除上表记录的实例: SQLite> DELETE FROM COMPANY; SQLite> VACUUM; 现在,COMPANY 表中的记录完全被删除,使用 SELECT 语句将没有任何输出。 SQLite 视图(View)视图(View)只不过是通过相关的名称存储在数据库中的一个 SQLite 语句。视图(View)实际上是一个以预定义的 SQLite 查询形式存在的表的组合。 视图(View)可以包含一个表的所有行或从一个或多个表选定行。视图(View)可以从一个或多个表创建,这取决于要创建视图的 SQLite 查询。、 视图(View)是一种虚表,允许用户实现以下几点:
SQLite 视图是只读的,因此可能无法在视图上执行 DELETE、INSERT 或 UPDATE 语句。但是可以在视图上创建一个触发器,当尝试 DELETE、INSERT 或 UPDATE 视图时触发,需要做的动作在触发器内容中定义。 创建视图SQLite 的视图是使用 CREATE VIEW 语句创建的。SQLite 视图可以从一个单一的表、多个表或其他视图创建。 CREATE VIEW 的基本语法如下: CREATE [TEMP | TEMPORARY] VIEW view_name AS SELECT column1,column2..... FROM table_name WHERE [condition]; 您可以在 SELECT 语句中包含多个表,这与在正常的 SQL SELECT 查询中的方式非常相似。如果使用了可选的 TEMP 或 TEMPORARY 关键字,则将在临时数据库中创建视图。 实例假设 COMPANY 表有以下记录: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 现在,下面是一个从 COMPANY 表创建视图的实例。视图只从 COMPANY 表中选取几列: sqlite> CREATE VIEW COMPANY_VIEW AS SELECT ID,NAME,AGE FROM COMPANY; 现在,可以查询 COMPANY_VIEW,与查询实际表的方式类似。下面是实例: sqlite> SELECT * FROM COMPANY_VIEW; 这将产生以下结果: ID NAME AGE ---------- ---------- ---------- 1 Paul 32 2 Allen 25 3 Teddy 23 4 Mark 25 5 David 27 6 Kim 22 7 James 24 删除视图要删除视图,只需使用带有 view_name 的 DROP VIEW 语句。DROP VIEW 的基本语法如下: sqlite> DROP VIEW view_name; 下面的命令将删除我们在前面创建的 COMPANY_VIEW 视图: sqlite> DROP VIEW COMPANY_VIEW; SQLite 事务(Transaction)事务(Transaction)是一个对数据库执行工作单元。事务(Transaction)是以逻辑顺序完成的工作单位或序列,可以是由用户手动操作完成,也可以是由某种数据库程序自动完成。 事务(Transaction)是指一个或多个更改数据库的扩展。例如,如果您正在创建一个记录或者更新一个记录或者从表中删除一个记录,那么您正在该表上执行事务。重要的是要控制事务以确保数据的完整性和处理数据库错误。 实际上,您可以把许多的 SQLite 查询联合成一组,把所有这些放在一起作为事务的一部分进行执行。 事务的属性事务(Transaction)具有以下四个标准属性,通常根据首字母缩写为 ACID:
事务控制使用下面的命令来控制事务:
事务控制命令只与 DML 命令 INSERT、UPDATE 和 DELETE 一起使用。他们不能在创建表或删除表时使用,因为这些操作在数据库中是自动提交的。 BEGIN TRANSACTION 命令事务(Transaction)可以使用 BEGIN TRANSACTION 命令或简单的 BEGIN 命令来启动。此类事务通常会持续执行下去,直到遇到下一个 COMMIT 或 ROLLBACK 命令。不过在数据库关闭或发生错误时,事务处理也会回滚。以下是启动一个事务的简单语法: BEGIN; or BEGIN TRANSACTION; COMMIT 命令COMMIT 命令是用于把事务调用的更改保存到数据库中的事务命令。 COMMIT 命令把自上次 COMMIT 或 ROLLBACK 命令以来的所有事务保存到数据库。 COMMIT 命令的语法如下: COMMIT; or END TRANSACTION; ROLLBACK 命令ROLLBACK 命令是用于撤消尚未保存到数据库的事务的事务命令。 ROLLBACK 命令只能用于撤销自上次发出 COMMIT 或 ROLLBACK 命令以来的事务。 ROLLBACK 命令的语法如下: ROLLBACK; 实例假设 COMPANY 表有以下记录: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 现在,让我们开始一个事务,并从表中删除 age = 25 的记录,最后,我们使用 ROLLBACK 命令撤消所有的更改。 sqlite> BEGIN; sqlite> DELETE FROM COMPANY WHERE AGE = 25; sqlite> ROLLBACK; 检查 COMPANY 表,仍然有以下记录: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 现在,让我们开始另一个事务,从表中删除 age = 25 的记录,最后我们使用 COMMIT 命令提交所有的更改。 sqlite> BEGIN; sqlite> DELETE FROM COMPANY WHERE AGE = 25; sqlite> COMMIT; 检查 COMPANY 表,有以下记录: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 3 Teddy 23 Norway 20000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 SQLite 子查询子查询或内部查询或嵌套查询是在另一个 SQLite 查询内嵌入在 WHERE 子句中的查询。 使用子查询返回的数据将被用在主查询中作为条件,以进一步限制要检索的数据。 子查询可以与 SELECT、INSERT、UPDATE 和 DELETE 语句一起使用,可伴随着使用运算符如 =、<、>、>=、<=、IN、BETWEEN 等。 以下是子查询必须遵循的几个规则:
SELECT 语句中的子查询使用子查询通常与 SELECT 语句一起使用。基本语法如下: SELECT column_name [,column_name ] FROM table1 [,table2 ] WHERE column_name OPERATOR (SELECT column_name [,column_name ] FROM table1 [,table2 ] [WHERE]) 实例假设 COMPANY 表有以下记录: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 现在,让我们检查 SELECT 语句中的子查询使用: sqlite> SELECT * FROM COMPANY WHERE ID IN (SELECT ID FROM COMPANY WHERE SALARY > 45000) ; 这将产生以下结果: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 INSERT 语句中的子查询使用子查询也可以与 INSERT 语句一起使用。INSERT 语句使用子查询返回的数据插入到另一个表中。在子查询中所选择的数据可以用任何字符、日期或数字函数修改。 基本语法如下: INSERT INTO table_name [ (column1 [,column2 ]) ] SELECT [ *|column1 [,column2 ] FROM table1 [,table2 ] [ WHERE VALUE OPERATOR ] 实例假设 COMPANY_BKP 的结构与 COMPANY 表相似,且可使用相同的 CREATE TABLE 进行创建,只是表名改为 COMPANY_BKP。现在把整个 COMPANY 表复制到 COMPANY_BKP,语法如下: sqlite> INSERT INTO COMPANY_BKP SELECT * FROM COMPANY WHERE ID IN (SELECT ID FROM COMPANY) ; UPDATE 语句中的子查询使用子查询可以与 UPDATE 语句结合使用。当通过 UPDATE 语句使用子查询时,表中单个或多个列被更新。 基本语法如下: UPDATE table SET column_name = new_value [ WHERE OPERATOR [ VALUE ] (SELECT COLUMN_NAME FROM TABLE_NAME) [ WHERE) ] 实例假设,我们有 COMPANY_BKP 表,是 COMPANY 表的备份。 下面的实例把 COMPANY 表中所有 AGE 大于或等于 27 的客户的 SALARY 更新为原来的 0.50 倍: sqlite> UPDATE COMPANY SET SALARY = SALARY * 0.50 WHERE AGE IN (SELECT AGE FROM COMPANY_BKP WHERE AGE >= 27 ); 这将影响两行,最后 COMPANY 表中的记录如下: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 10000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 42500.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 DELETE 语句中的子查询使用子查询可以与 DELETE 语句结合使用,就像上面提到的其他语句一样。 基本语法如下: DELETE FROM TABLE_NAME [ WHERE OPERATOR [ VALUE ] (SELECT COLUMN_NAME FROM TABLE_NAME) [ WHERE) ] 实例假设,我们有 COMPANY_BKP 表,是 COMPANY 表的备份。 下面的实例删除 COMPANY 表中所有 AGE 大于或等于 27 的客户记录: sqlite> DELETE FROM COMPANY WHERE AGE IN (SELECT AGE FROM COMPANY_BKP WHERE AGE > 27 ); 这将影响两行,最后 COMPANY 表中的记录如下: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 42500.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 SQLite Autoincrement(自动递增)SQLite 的 AUTOINCREMENT 是一个关键字,用于表中的字段值自动递增。我们可以在创建表时在特定的列名称上使用 AUTOINCREMENT 关键字实现该字段值的自动增加。 关键字 AUTOINCREMENT 只能用于整型(INTEGER)字段。 语法AUTOINCREMENT 关键字的基本用法如下: CREATE TABLE table_name( column1 INTEGER AUTOINCREMENT,column2 datatype,column3 datatype,..... columnN datatype,); 实例假设要创建的 COMPANY 表如下所示: sqlite> CREATE TABLE COMPANY( ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT NOT NULL,AGE INT NOT NULL,ADDRESS CHAR(50),SALARY REAL ); 现在,向 COMPANY 表插入以下记录: INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY) VALUES ( 'Paul',32,'California',20000.00 ); INSERT INTO COMPANY (NAME,SALARY) VALUES ('Allen',25,'Texas',15000.00 ); INSERT INTO COMPANY (NAME,SALARY) VALUES ('Teddy',23,'Norway',SALARY) VALUES ( 'Mark','Rich-Mond ',65000.00 ); INSERT INTO COMPANY (NAME,SALARY) VALUES ( 'David',27,85000.00 ); INSERT INTO COMPANY (NAME,SALARY) VALUES ( 'Kim',22,'South-Hall',45000.00 ); INSERT INTO COMPANY (NAME,SALARY) VALUES ( 'James',24,'Houston',10000.00 ); 这将向 COMPANY 表插入 7 个元组,此时 COMPANY 表的记录如下: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 SQLite 注入如果您的站点允许用户通过网页输入,并将输入内容插入到 SQLite 数据库中,这个时候您就面临着一个被称为 SQL 注入的安全问题。本章节将向您讲解如何防止这种情况的发生,确保脚本和 SQLite 语句的安全。 注入通常在请求用户输入时发生,比如需要用户输入姓名,但用户却输入了一个 SQLite 语句,而这语句就会在不知不觉中在数据库上运行。 永远不要相信用户提供的数据,所以只处理通过验证的数据,这项规则是通过模式匹配来完成的。在下面的实例中,用户名 username 被限制为字母数字字符或者下划线,长度必须在 8 到 20 个字符之间 - 请根据需要修改这些规则。 if (preg_match("/^w{8,20}$/",$_GET['username'],$matches)){ $db = new SQLiteDatabase('filename'); $result = @$db->query("SELECT * FROM users WHERE username=$matches[0]"); }else{ echo "username not accepted"; } 为了演示这个问题,假设考虑此摘录:To demonstrate the problem,consider this excerpt: $name = "Qadir'; DELETE FROM users;"; @$db->query("SELECT * FROM users WHERE username='{$name}'"); 函数调用是为了从用户表中检索 name 列与用户指定的名称相匹配的记录。正常情况下,$name 只包含字母数字字符或者空格,比如字符串 ilia。但在这里,向 $name 追加了一个全新的查询,这个对数据库的调用将会造成灾难性的问题:注入的 DELETE 查询会删除 users 的所有记录。 虽然已经存在有不允许查询堆叠或在单个函数调用中执行多个查询的数据库接口,如果尝试堆叠查询,则会调用失败,但 SQLite 和 PostgreSQL 里仍进行堆叠查询,即执行在一个字符串中提供的所有查询,这会导致严重的安全问题。 防止 SQL 注入在脚本语言中,比如 PERL 和 PHP,您可以巧妙地处理所有的转义字符。编程语言 PHP 提供了字符串函数 sqlite_escape_string() 来转义对于 SQLite 来说比较特殊的输入字符。 if (get_magic_quotes_gpc()) { $name = sqlite_escape_string($name); } $result = @$db->query("SELECT * FROM users WHERE username='{$name}'"); 虽然编码使得插入数据变得安全,但是它会呈现简单的文本比较,在查询中,对于包含二进制数据的列,LIKE 子句是不可用的。 请注意,addslashes() 不应该被用在 SQLite 查询中引用字符串,它会在检索数据时导致奇怪的结果。 SQLite Explain(解释)在 SQLite 语句之前,可以使用 "EXPLAIN" 关键字或 "EXPLAIN QUERY PLAN" 短语,用于描述表的细节。 如果省略了 EXPLAIN 关键字或短语,任何的修改都会引起 SQLite 语句的查询行为,并返回有关 SQLite 语句如何操作的信息。
语法EXPLAIN 的语法如下: EXPLAIN [SQLite Query] EXPLAIN QUERY PLAN 的语法如下: EXPLAIN QUERY PLAN [SQLite Query] 实例假设 COMPANY 表有以下记录: ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 20000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0 现在,让我们检查 SELECT 语句中的 Explain 使用: sqlite> EXPLAIN SELECT * FROM COMPANY WHERE Salary >= 20000; 这将产生以下结果: addr opcode p1 p2 p3 ---------- ---------- ---------- ---------- ---------- 0 Goto 0 19 1 Integer 0 0 2 OpenRead 0 8 3 SetNumColu 0 5 4 Rewind 0 17 5 Column 0 4 6 RealAffini 0 0 7 Integer 20000 0 8 Lt 357 16 collseq(BI 9 Rowid 0 0 10 Column 0 1 11 Column 0 2 12 Column 0 3 13 Column 0 4 14 RealAffini 0 0 15 Callback 5 0 16 Next 0 5 17 Close 0 0 18 Halt 0 0 19 Transactio 0 0 20 VerifyCook 0 38 21 Goto 0 1 22 Noop 0 0 现在,让我们检查 SELECT 语句中的 Explain Query Plan 使用: SQLite> EXPLAIN QUERY PLAN SELECT * FROM COMPANY WHERE Salary >= 20000; order from detail ---------- ---------- ------------- 0 0 TABLE COMPANY SQLite VacuumVACUUM 命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件。这消除了空闲页,把表中的数据排列为连续的,另外会清理数据库文件结构。 如果表中没有明确的整型主键(INTEGER PRIMARY KEY),VACUUM 命令可能会改变表中条目的行 ID(ROWID)。VACUUM 命令只适用于主数据库,附加的数据库文件是不可能使用 VACUUM 命令。 如果有一个活动的事务,VACUUM 命令就会失败。VACUUM 命令是一个用于内存数据库的任何操作。由于 VACUUM 命令从头开始重新创建数据库文件,所以 VACUUM 也可以用于修改许多数据库特定的配置参数。 手动 VACUUM下面是在命令提示符中对整个数据库发出 VACUUM 命令的语法: $sqlite3 database_name "VACUUM;" 您也可以在 SQLite 提示符中运行 VACUUM,如下所示: sqlite> VACUUM; 您也可以在特定的表上运行 VACUUM,如下所示: sqlite> VACUUM table_name; 自动 VACCUM(Auto-VACUUM)SQLite 的 Auto-VACUUM 与 VACUUM 不大一样,它只是把空闲页移到数据库末尾,从而减小数据库大小。通过这样做,它可以明显地把数据库碎片化,而 VACUUM 则是反碎片化。所以 Auto-VACUUM 只会让数据库更小。 在 SQLite 提示符中,您可以通过下面的编译运行,启用/禁用 SQLite 的 Auto-VACUUM: sqlite> PRAGMA auto_vacuum = NONE; -- 0 means disable auto vacuum sqlite> PRAGMA auto_vacuum = INCREMENTAL; -- 1 means enable incremental vacuum sqlite> PRAGMA auto_vacuum = FULL; -- 2 means enable full auto vacuum 您可以从命令提示符中运行下面的命令来检查 auto-vacuum 设置: $sqlite3 database_name "PRAGMA auto_vacuum;" SQLite 日期 & 时间SQLite 支持以下五个日期和时间函数: | 序号 | 函数 | 实例 | 1 date(timestring,modifiers...) 以 YYYY-MM-DD 格式返回日期。 2 time(timestring,modifiers...) 以 HH:MM:SS 格式返回时间。 3 datetime(timestring,modifiers...) 以 YYYY-MM-DD HH:MM:SS 格式返回。 4 julianday(timestring,modifiers...) 这将返回从格林尼治时间的公元前 4714 年 11 月 24 日正午算起的天数。 5 strftime(timestring,modifiers...) 这将根据第一个参数指定的格式字符串返回格式化的日期。具体格式见下边讲解。序号 | 时间字符串 | 实例 | 1 YYYY-MM-DD 2010-12-30 2 YYYY-MM-DD HH:MM 2010-12-30 12:10 3 YYYY-MM-DD HH:MM:SS.SSS 2010-12-30 12:10:04.100 4 MM-DD-YYYY HH:MM 30-12-2010 12:10 5 HH:MM 12:10 6 YYYY-MM-DDTHH:MM 2010-12-30 12:10 7 HH:MM:SS 12:10:01 8 YYYYMMDD HHMMSS 20101230 121001 9 now 2013-05-07替换 | 描述 | %d 一月中的第几天,01-31 %f 带小数部分的秒,SS.SSS %H 小时,00-23 %j 一年中的第几天,001-366 %J 儒略日数,DDDD.DDDD %m 月,00-12 %M 分,00-59 %s 从 1970-01-01 算起的秒数 %S 秒,00-59 %w 一周中的第几天,0-6 (0 is Sunday) %W 一年中的第几周,01-53 %Y 年,YYYY %% % symbol序号 | 函数 & 描述 | 1 SQLite COUNT 函数
---|