一篇文章搞懂 SQLite3库-常用的 SQL 语句和示例

SQLite3 是一个轻量级的开源关系数据库管理系统,它在许多应用程序中被广泛使用,尤其是在移动应用和嵌入式系统中。

  • 自包含:SQLite 是一个自包含的数据库引擎,不依赖于外部服务器或其他依赖。所有的数据库管理功能都嵌入在一个库中,简化了部署和维护。
  • 轻量级:SQLite 的库文件很小,通常不到 1 MB,适合资源受限的环境,如手机和嵌入式设备。
  • 零配置:使用 SQLite 不需要复杂的安装和配置。数据库文件是一个普通的文件,应用程序可以直接读写它,无需专门的数据库服务器。
  • 事务支持:SQLite 支持 ACID(原子性、一致性、隔离性、持久性)事务,确保数据的完整性和可靠性。
  • SQL 支持:SQLite 支持标准的 SQL 查询语言,包括数据定义、数据操作和数据控制语言,但可能不支持某些高级功能或特性(如存储过程)。
  • 跨平台:SQLite 支持多种操作系统,包括 Windows、macOS、Linux、Android 和 iOS。它的数据库文件格式在不同平台之间是兼容的。
  • 嵌入式:SQLite 通常被嵌入到应用程序中,不需要额外的数据库服务器进程。它直接与应用程序的进程进行通信。
  • 多线程支持:SQLite 可以在多线程环境中使用,但需要正确配置和使用相应的线程模式(单线程、多线程、序列化)。
  • 文件格式:SQLite 数据库是一个文件,所有数据(表、索引、视图)都存储在一个单一的文件中,简化了备份和迁移。
  • 无锁设计:SQLite 的锁机制设计是为了尽可能地减少锁冲突,支持高并发的读取操作。

这些特点使 SQLite 成为一个非常灵活且易于集成的数据库解决方案,特别适合小型到中型应用和不需要复杂数据库管理的场景。

1. 创建表

SQL 语句:


CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    age INTEGER
);

Swift 示例:
创建一个 users 表,包含三列:id(主键且自动递增)、name(文本且不能为空)和 age(整数)。


import SQLite3

var db: OpaquePointer?

// 打开数据库
func openDatabase() {
    let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("example.db")

    if sqlite3_open(fileURL.path, &db) != SQLITE_OK {
        print("Error opening database")
    } else {
        print("Database opened successfully")
    }
}

// 关闭数据库
func closeDatabase() {
    if sqlite3_close(db) != SQLITE_OK {
        print("Error closing database")
    } else {
        print("Database closed successfully")
    }
}

func createTable() {
    let createTableString = """
    CREATE TABLE users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        age INTEGER
    );
    """
    
    if sqlite3_exec(db, createTableString, nil, nil, nil) != SQLITE_OK {
        print("Error creating table")
    } else {
        print("Table created successfully")
    }
}

SQL 语句参数:

  • sqlite3_open:打开数据库文件。如果数据库不存在,SQLite 会创建它。
  • sqlite3_close:关闭数据库连接并释放资源。
  • CREATE TABLE users (...):定义表结构。users 是表名,id, name, age 是列名及其属性。

Swift 示例:

db:SQLite 数据库的指针,指向打开的数据库。
createTableString:包含 SQL 语句的字符串,用于创建表。
sqlite3_exec():执行 SQL 语句。参数包括数据库指针、SQL 语句、回调函数(这里为 nil)、错误信息(这里为 nil)和 nil(用于回调函数传递用户数据)

2. 创建表

SQL 语句:


INSERT INTO users (name, age) VALUES ('Alice', 30);

Swift 示例:
将用户数据插入到 users 表中。? 是占位符,用于防止 SQL 注入。


func insertUser(name: String, age: Int) {
    let insertStatementString = "INSERT INTO users (name, age) VALUES (?, ?);"
    var insertStatement: OpaquePointer?

    if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
        sqlite3_bind_text(insertStatement, 1, name, -1, nil)
        sqlite3_bind_int(insertStatement, 2, Int32(age))

        if sqlite3_step(insertStatement) == SQLITE_DONE {
            print("Successfully inserted user.")
        } else {
            print("Failed to insert user.")
        }
    } else {
        print("Failed to prepare insert statement.")
    }
    sqlite3_finalize(insertStatement)
}

SQL 语句参数:

  • INSERT INTO users (name, age) VALUES (?, ?);:指定要插入的表、列名和对应的值。? 是占位符,用于安全地插入数据。

Swift 示例:

  • insertUser(name: String, age: Int):函数参数,用于指定要插入的用户数据。
  • insertStatementString:SQL 插入语句的字符串。
  • insertStatement:准备好的 SQL 语句的指针。
  • sqlite3_prepare_v2():准备 SQL 语句,参数包括数据库指针、SQL 语句、语句长度、准备好的语句指针、nil(用于错误信息)。
  • sqlite3_bind_text()sqlite3_bind_int():绑定参数值到 SQL 语句中的占位符。
  • sqlite3_step():执行 SQL 语句。
  • sqlite3_finalize():释放准备好的 SQL 语句资源。

3. 查询数据

SQL 语句:


SELECT * FROM users;

Swift 示例:
从 users 表中查询所有数据。sqlite3_step 用于遍历结果集


func queryUsers() {
    let queryStatementString = "SELECT * FROM users;"
    var queryStatement: OpaquePointer?

    if sqlite3_prepare_v2(db, queryStatementString, -1, &queryStatement, nil) == SQLITE_OK {
        while sqlite3_step(queryStatement) == SQLITE_ROW {
            let id = sqlite3_column_int(queryStatement, 0)
            let name = String(cString: sqlite3_column_text(queryStatement, 1))
            let age = sqlite3_column_int(queryStatement, 2)

            print("Query Result:")
            print("Id: \(id), Name: \(name), Age: \(age)")
        }
    } else {
        print("Failed to prepare query statement.")
    }
    sqlite3_finalize(queryStatement)
}

SQL 语句参数:

  • SELECT * FROM users;:从表 users 中选择所有列和行。

Swift 示例:

  • queryUsers():函数用于查询并输出用户数据。
  • queryStatementString:包含查询 SQL 语句的字符串。
  • queryStatement:准备好的查询语句的指针。
  • sqlite3_prepare_v2():准备查询 SQL 语句。
  • sqlite3_step():执行查询,逐行读取数据。
  • sqlite3_column_int()sqlite3_column_text():从查询结果中提取列值。0、1、2 是列索引。

4. 更新数据

SQL 语句:


UPDATE users SET age = 31 WHERE name = 'Alice';

Swift 示例:
更新 users 表中符合条件的数据。参数绑定用于防止 SQL 注入。


func updateUser(name: String, newAge: Int) {
    let updateStatementString = "UPDATE users SET age = ? WHERE name = ?;"
    var updateStatement: OpaquePointer?

    if sqlite3_prepare_v2(db, updateStatementString, -1, &updateStatement, nil) == SQLITE_OK {
        sqlite3_bind_int(updateStatement, 1, Int32(newAge))
        sqlite3_bind_text(updateStatement, 2, name, -1, nil)

        if sqlite3_step(updateStatement) == SQLITE_DONE {
            print("Successfully updated user.")
        } else {
            print("Failed to update user.")
        }
    } else {
        print("Failed to prepare update statement.")
    }
    sqlite3_finalize(updateStatement)
}

SQL 语句参数:

  • UPDATE users SET age = ? WHERE name = ?;:指定要更新的表、更新内容和条件。? 是占位符。

Swift 示例:

  • updateUser(name: String, newAge: Int):函数参数,指定要更新的用户和新年龄。
  • updateStatementString:包含更新 SQL 语句的字符串。
  • updateStatement:准备好的 SQL 语句的指针。
  • sqlite3_prepare_v2():准备 SQL 语句。
  • sqlite3_bind_int()sqlite3_bind_text():绑定更新值到占位符。
  • sqlite3_step():执行更新语句。
  • sqlite3_finalize():释放准备好的 SQL 语句资源。

5. 删除数据

SQL 语句:


DELETE FROM users WHERE name = 'Alice';

Swift 示例:
删除 users 表中符合条件的数据。参数绑定同样用于防止 SQL 注入。


func deleteUser(name: String) {
    let deleteStatementString = "DELETE FROM users WHERE name = ?;"
    var deleteStatement: OpaquePointer?

    if sqlite3_prepare_v2(db, deleteStatementString, -1, &deleteStatement, nil) == SQLITE_OK {
        sqlite3_bind_text(deleteStatement, 1, name, -1, nil)

        if sqlite3_step(deleteStatement) == SQLITE_DONE {
            print("Successfully deleted user.")
        } else {
            print("Failed to delete user.")
        }
    } else {
        print("Failed to prepare delete statement.")
    }
    sqlite3_finalize(deleteStatement)
}

SQL 语句参数:

  • DELETE FROM users WHERE name = ?;:指定要删除的表和条件。 ? 是占位符。

Swift 示例:

  • deleteUser(name: String):函数参数,指定要删除的用户。
  • deleteStatementString:包含删除 SQL 语句的字符串。
  • deleteStatement:准备好的删除语句的指针。
  • sqlite3_prepare_v2():准备 SQL 语句。
  • sqlite3_bind_text():绑定删除条件到占位符。
  • sqlite3_step():执行删除语句。
  • sqlite3_finalize():释放准备好的 SQL 语句资源。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容