SQLite 数据库使用指导

← 返回SQLite 数据库组件参考 · 全部使用指导

SQLite 数据库使用指导

不可见组件,内置的迷你本地数据库引擎:兼容主流 SQL 语法,支持事务与异步执行。 现已内置到设计器的「数据存储」分类,无需再导入拓展;积木方法名与原拓展一致, 更详尽的历史图文说明保留在原拓展文档。

快速上手:本地记事本

界面:拖入 文本输入框1、按钮1(文字改为「添加」)、列表显示框1,以及一个 SQLite(默认名 SQLite1)、计时器1(关闭默认启用)和 标签_状态。

代码块:屏幕打开时建表并显示已有记录;点「添加」写入一条并刷新。

各案例独立使用;组合到同一屏幕时,将同名事件的处理合并到一个事件积木中。

global 等待次数 = 0

when Screen1.Initialize() {
  计时器1.TimerEnabled = false
  计时器1.TimerInterval = 200
  SQLite1.OpenDatabase()
  计时器1.TimerEnabled = true
}

when 计时器1.Timer() {
  等待次数 = 等待次数 + 1
  if SQLite1.IsDatabaseOpen() {
    计时器1.TimerEnabled = false
    var 建表成功 = SQLite1.Execute("CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT)", list())
    if 建表成功 { 刷新列表() }
    else { 标签_状态.Text = "建表失败,请查看SQL错误。" }
  } else if 等待次数 >= 30 {
    计时器1.TimerEnabled = false
    标签_状态.Text = "数据库尚未打开,请检查SQL错误后重新打开。"
  }
}

when 按钮1.Click() {
  if SQLite1.IsDatabaseOpen() and trim(文本输入框1.Text) != "" {
    var 行编号 = SQLite1.Insert("notes", list("content"), list(文本输入框1.Text))
    if 行编号 >= 0 { 文本输入框1.Text = "" 刷新列表() }
  } else { 标签_状态.Text = "先等待数据库打开,并输入内容。" }
}

when SQLite1.SQLError(消息) { 标签_状态.Text = 消息 }

procedure 刷新列表() {
  列表显示框1.Elements = SQLite1.SelectSQL("SELECT content FROM notes ORDER BY id DESC", list())
}

运行效果:输入文字点「添加」,最新一条出现在列表顶部;退出应用再打开,记录仍在。

要点:

  • 必须先打开数据库(OpenDatabase),并用 IsDatabaseOpen() 确认已打开再执行 SQL。鸿蒙系统打开是异步过程,不能在调用后立即假定已就绪;上述计时器等待真实状态,不制造完成事件。未打开时执行返回假,并可能触发SQL错误。
  • 插入(表名,列列表,值)(Insert)的第 3 个参数是一行的值(与列名一一对应的扁平列表),不要再套一层列表。
  • SQL查询(SQL语句,绑定参数)(SelectSQL)返回「行的列表」:只查一列时每行直接就是该列的值(上例可直接设给列表显示框); 查多列时每行是一个列表,按列序号取值(行[1] 为第一列)。
  • 数据量大时改用带「异步」的版本(如 异步SQL查询(标签,SQL语句,绑定参数)(SelectSQLAsync)),结果在对应的「完成时」事件里拿,避免卡界面。

搭建与测试

在设计器拖入本组件和案例涉及的按钮、标签、布局等组件,按案例中的名称重命名。先运行最小案例,确认事件返回,再增加业务逻辑。示例中的素材先上传到项目,服务器地址、令牌、文件路径换成自己的值。

可见组件需要有非零宽高;不可见工具组件必须由属性或方法启动。设计器展示样式不等于运行时已加载数据或绑定目标。联机测试应使用包含本组件的 AI 伴侣;涉及系统入口或权限的行为还要编译安装后验证。

案例:异步读取记事本

在最小记事本案例初始化并建表之后,增加一个查询按钮。绑定参数使用列表,查询结果在 AfterSelect 中读取。

when 按钮_查询.Click() {
  SQLite1.SelectSQLAsync("notes", "SELECT content FROM notes ORDER BY id DESC", list())
}
when SQLite1.AfterSelect(标签, 行数, 行数据) {
  if 标签 == "notes" {
    列表显示框1.Elements = 行数据
  }
}
when SQLite1.SQLError(消息) {
  标签1.Text = 消息
}

先打开数据库再查询;数据库名变化会打开另一个文件。正式业务 SQL 使用绑定参数,不把输入框内容拼进 SQL。

属性、方法与事件速查

完整参数类型、默认值和平台说明见组件参考。下表按调用入口列出用途;有完成事件的方法在事件中读取结果。

入口 用途
数据库名(DBName) 指定数据库的名称,默认值:db.sqlite3
数据库版本(DBVersion) 指定数据库的版本,默认值:1。
返回列名(ReturnColumnNames) 指定结果列表中是否包含列名,默认值:假(不包含)。更多信息,请参阅查询相关块。
开始事务(BeginTransaction) 在打开的数据库上开始一个事务。 支持事务嵌套。
关闭数据库(CloseDatabase) 关闭数据库。 如果数据库已关闭,则不会发生任何操作。 任何未提交的事务都将被回滚。
提交事务(CommitTransaction) 提交最后一次打开的事务。
数据库是否存在(DatabaseExists) 如果数据库文件存在则返回 真,否则返回 假。
数据库路径(DatabasePath) 返回数据库的完整路径,即使库不存在。
删除(表名,WHERE条件,绑定参数)(Delete) 执行 SQL DELETE 语句。WHERE条件可省略,省略时删除表中全部行;每个绑定参数替换条件里对应的问号。传入条件时返回受影响的行数,否则返回 0;出错或数据库未打开时返回 -1。
删除数据库(DeleteDatabase) 删除已关闭的数据库。将永久删除数据库文件。
执行(SQL语句,绑定参数)(Execute) 执行单个参数化的 SQL语句(非 SELECT语句,如:create table、insert、update、delete等),并返回执行是否成功。 每个绑定参数都会替换查询中 WHERE 子句中对应的 “?”。 如果数据库未打开,则返回 假。
异步执行(标签,SQL语句,绑定参数)(ExecuteAsync) 异步执行单个参数化的 SQL语句(非 SELECT语句,如:create table、insert、update、delete等),执行完成后将触发 AfterExecute 事件。 参数tag 会在 AfterExecute 事件中标识此调用的结果。
执行文件(文件名)(ExecuteFile) 执行文件中的多条 SQL 语句,返回成功执行的语句数量。文件每行应为一条完整的非 SELECT 语句,行尾可带分号;单行(–)与多行注释会被忽略;支持用反斜杠续行,反斜杠n 会被替换为真实换行;遇到第一个错误即停止。数据库未打开时返回 -1。文件名以 / 开头表示从 SD 卡指定文件读取,以 //(两个斜杠)开头表示读取应用打包的资源(伴侣同样适用);不以斜杠开头时,打包的应用从应用私有存储读取,伴侣从 /sdcard/AppInventor/data 读取。
导出数据库(文件名)(ExportDatabase) 将当前已关闭的数据库导出到指定文件。 导出的文件是一个完整的 SQLite 数据库。 如果导入成功,则返回 真,否则返回 假。
导入数据库(文件名)(ImportDatabase) 导入一个 SQLite 数据库文件,完全替换当前已关闭的数据库。 导入成功则返回 真,否则返回 假。
插入(表名,列列表,值)(Insert) 执行 SQL INSERT 语句。列名为列名列表,值为对应列值的列表。返回新插入行的行 ID;出错或数据库未打开时返回 -1。
插入文件(表名,文件名)(InsertFile) 从文件向表中插入多行数据。文件第一行应为逗号分隔的列名,其余每行是对应各列的值;空行忽略;支持用反斜杠续行,反斜杠n 替换为真实换行;遇到第一个错误即停止。数据库未打开时返回 -1。文件名以 / 开头表示从 SD 卡读取,以 // 开头表示读取应用打包资源(伴侣同样适用);否则打包应用从应用私有存储读取,伴侣从 /sdcard/AppInventor/data 读取。
数据库是否打开(IsDatabaseOpen) 如果数据库已打开则返回 真,否则返回 假。
打开数据库(OpenDatabase) 打开数据库。 如果数据库已打开,则不会发生任何事情。
替换(表名,列列表,值)(Replace) 执行 SQL REPLACE 语句。列名为列名列表,值为对应列值的列表。返回新插入或更新行的行 ID;出错或数据库未打开时返回 -1。
回滚事务(RollbackTransaction) 回滚最后一次打开的事务。
SQL查询(SQL语句,绑定参数)(SelectSQL) 执行一条带参数的 SQL SELECT 语句并返回记录列表。每个绑定参数替换 WHERE 子句里对应的问号。只查一列时,返回列表的每个元素就是该列的值;查多列时每个元素本身是各列值的列表。若开启「返回列名」,每个列值为 [列名, 值] 形式的两元素列表。数据库未打开时返回空列表。
异步SQL查询(标签,SQL语句,绑定参数)(SelectSQLAsync) 异步执行一条带参数的 SQL SELECT 语句。标记用于在「查询完成时」事件中识别本次调用,详见「SQL查询」方法。
表是否存在(表名)(TableExists) 如果数据库中该表存在,则返回 真; 如果表不存在 或 发生错误 或 数据库未打开,则返回 假。
全部表名(TableNames) 返回数据库中所有表的名称(列表)。 如果发生错误或数据库未打开,则返回空列表。
表行数(表名)(TableRowCount) 返回表中的行数,如果发生错误或数据库未打开,则返回 -1。
更新(表名,列列表,值,WHERE条件,绑定参数)(Update) 执行 SQL UPDATE 语句。列名为列名列表,值为对应列值的列表。WHERE条件可省略,省略时更新表中全部行;每个绑定参数替换条件里对应的问号。返回受影响的行数;出错或数据库未打开时返回 -1。
执行完成时(标签,返回结果)(AfterExecute) 此事件在 ExecuteAsync 执行完成后触发。 标签对应调用时传入的标签;返回结果为布尔值,表示执行是否成功。
查询完成时(标签,行数,行数据)(AfterSelect) 此事件在异步 Select 调用后触发。 提供原始调用中指定的标签、返回的行数以及结果行数据。
数据库创建时(DatabaseCreated) 当数据库创建时,会触发此事件。
数据库升级时(旧版本,新版本)(DatabaseUpgrade) 数据库升级时触发。事件带有旧版本号和新版本号,可据此修改数据库结构以适配版本变化。
SQL出错时(消息)(SQLError) 发生 SQL错误时触发此事件,并提供错误信息。

常见问题与验收

检查项 操作与预期
初始化 对照案例检查是否已经调用加载、注册、连接或显示方法;仅拖入组件不会替你执行这些步骤。
结果返回 将成功事件和失败事件都接到标签,记录事件参数;异步操作完成前不读取结果属性。
输入配置 检查素材名大小写、网址是否为直接资源地址、文件是否存在、编号和索引是否在范围内。
平台与权限 按组件参考中的平台说明测试;授权被拒绝时应有明确提示,不继续假定操作成功。
最小案例 先验证页面中的最小案例,再验证第二个场景;重复操作、取消、返回屏幕后结果应符合事件说明。

鸿蒙连接与备份时序

  • 先设置数据库名和版本,再打开。组件不在构造阶段偷偷打开默认库。切换名称会释放旧连接;先确认关闭完成,再打开新库。
  • 鸿蒙系统关闭也是异步操作。关闭后立即导入、导出可能返回假并提示仍在关闭;稍后重试,只有返回真才表示复制已完成。不把 IsDatabaseOpen() 为假理解成系统文件已经释放。
  • 删除数据库会等待当前打开或关闭请求结束后执行;期间拒绝重新打开。删除后通过数据库是否存在确认结果,未出现“删除完成”事件。
  • //setup.sql 等素材名在伴侣由实际素材解析器读取,独立HAP从打包的 rawfile/assets 读取。SQL文件每行一条语句;CSV首行列名,不支持完整CSV引号转义语法。

鸿蒙API18及以上按实际列类型返回数字与文本,中文名称和文本编号“001”不会转成0或丢掉前导零。更旧系统没有同步列类型接口时保留字符串;用于计算时先检查并转换数字。

完整 .aia 源码与操作指导

下载 .aia 源码

采集设备温度与电量的本地数据库应用,涵盖全部数据库接口。自带SQL/CSV素材,保存与恢复均操作本案例独立库;先等待实际连接就绪,再显示记录,不用固定延时猜建表完成。

导入 SQLiteAllFeatures.aia,连接最新伴侣,或编译独立安装包。真机/伴侣运行尚未实测。

API / 功能 操作入口 预期结果
DBName、DBVersion、ReturnColumnNames、设计器 固定案例库;关闭后应用版本;勾选返回列名 真实读回;只操作device-records-case.sqlite3,不操作用户库
OpenDatabase、IsDatabaseOpen、Execute 打开,等待真实连接就绪后自动建表 首次空表才插入两条演示记录,重开不清空保存数据
CloseDatabase、DatabasePath、DatabaseExists 关闭、读取状态 实际打开状态、文件存在与绝对路径;鸿蒙关闭异步,备份有额外保护
Insert、Replace、Update、Delete 插入后真实ID填入编号,修改或删除该行 显示真实新行ID/受影响行数;占位符参数绑定
SelectSQL、TableExists、TableNames、TableRowCount 同步查询、读取状态 实际记录、表名与数量;返回列名可切换
SelectSQLAsync、AfterSelect 异步查询 标签取真实tag、行数、rows,不调用假完成事件
ExecuteAsync、AfterExecute 异步写入201 真完成事件显示tag与result,成功才刷新
BeginTransaction、CommitTransaction、RollbackTransaction 提交样本、回滚样本 提交后按ID能查到,回滚后按ID空列表
ExecuteFile、InsertFile SQL素材、CSV素材 SQL每行一条,2条;CSV2行;重复操作替换本案例预留100—102
ExportDatabase、ImportDatabase 关闭后导出;修改数据后关闭再导入,重新打开 以实际返回真判断完成;备份恢复,不复用旧缓存
DeleteDatabase 勾选确认、删除后稍后查状态 仅删除本案例库;存在为假后可重新打开,备份保留
DatabaseCreated、DatabaseUpgrade 首次建库;关闭、版本改3、打开 真实创建、2→3升级事件;降低版本不伪造升级
SQLError、空输入、重复操作 不存在表SQL,非法编号、空设备名 错误可见;无破坏性全表删除,正常操作可继续

所有返回值均用于界面反馈,错误由底部错误区展示。设计器采用明确非默认配置,初始化与界面同步。API 覆盖检查按最终 AIA 检查方法、事件、属性读取与设置及设计器配置,不能替代真实设备验证。

设备采集记录数据库

导入方法:项目 → 导入项目(.aia)→ 选择下载的 .aia 源码文件。 采集设备温度与电量的本地数据库应用,涵盖全部数据库接口。自带SQL/CSV素材,保存与恢复均操作本案例独立库;先等待实际连接就绪,再显示记录,不用固定延时猜建表完成。 覆盖检查 38/38。首次载入及保存重开均0个错误,真实后台导入、安装包编译通过;真机/伴侣/硬件联调尚未实测。全部属性读写、方法与事件的操作入口和预期结果见组件指导。

按这个顺序验证闭环

  1. 第一次运行等待上方“已打开”为真,列表应显示温度计001与电量计001;关闭/重新打开后记录保留。
  2. 名称填“设备’001”、数值23.5,点击插入。使用参数绑定,名称中的单引号也能保存。新增行的实际编号自动填入编号框;修改数值后更新、查询,再删除该编号。
  3. 关闭返回列名后只显示值列表;勾选后每列显示列名和值。分别执行同步、异步查询,检查真实完成事件参数。
  4. 提交事务后新记录存在;回滚事务后按插入时ID查询为空。不要把拿到行ID理解为事务已经提交。
  5. SQL素材成功数应为2;CSV插入行数2。重复测试只清理该素材的101、102,再插入,其他记录保留。文件每行一条SQL;CSV是简单逗号分隔,不支持引号包裹逗号。
  6. 关闭,稍后导出,只有返回真才继续。重新打开插入一个“备份后新增”记录,关闭后导入备份(返回真),再打开,该新增记录应消失,备份时的记录恢复。尚在关闭时返回假属于保护,重试前看错误区;缺失备份返回假。
  7. 当前设计器版本2。关闭、改版本3、应用配置、稍后打开;只有真实升级事件才显示2→3。首次创建事件只在新库首次产生。工程拒绝降级,并用独立微数据库保存已应用版本,重启仍按该版本打开,不退回设计器版本2。
  8. 测完可勾选永久删除确认,仅删除本案例库;稍后读取不存在,再重新打开。备份留在应用私有目录,不会被删除按钮移除。

工程内素材

  • setup.sql:可重复的建表与编号100示例。
  • readings.csv:编号101、102,两条真实CSV样本。

安卓与鸿蒙使用相同SQL、参数与素材;鸿蒙系统连接/关闭是异步过程,工程以真实状态和返回值判断。数据库、备份路径来自组件与文件管理器的实际应用私有目录,未填写共享存储固定路径。

文档反馈