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 源码与操作指导
采集设备温度与电量的本地数据库应用,涵盖全部数据库接口。自带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个错误,真实后台导入、安装包编译通过;真机/伴侣/硬件联调尚未实测。全部属性读写、方法与事件的操作入口和预期结果见组件指导。
按这个顺序验证闭环
- 第一次运行等待上方“已打开”为真,列表应显示温度计001与电量计001;关闭/重新打开后记录保留。
- 名称填“设备’001”、数值23.5,点击插入。使用参数绑定,名称中的单引号也能保存。新增行的实际编号自动填入编号框;修改数值后更新、查询,再删除该编号。
- 关闭返回列名后只显示值列表;勾选后每列显示列名和值。分别执行同步、异步查询,检查真实完成事件参数。
- 提交事务后新记录存在;回滚事务后按插入时ID查询为空。不要把拿到行ID理解为事务已经提交。
- SQL素材成功数应为2;CSV插入行数2。重复测试只清理该素材的101、102,再插入,其他记录保留。文件每行一条SQL;CSV是简单逗号分隔,不支持引号包裹逗号。
- 关闭,稍后导出,只有返回真才继续。重新打开插入一个“备份后新增”记录,关闭后导入备份(返回真),再打开,该新增记录应消失,备份时的记录恢复。尚在关闭时返回假属于保护,重试前看错误区;缺失备份返回假。
- 当前设计器版本2。关闭、改版本3、应用配置、稍后打开;只有真实升级事件才显示2→3。首次创建事件只在新库首次产生。工程拒绝降级,并用独立微数据库保存已应用版本,重启仍按该版本打开,不退回设计器版本2。
- 测完可勾选永久删除确认,仅删除本案例库;稍后读取不存在,再重新打开。备份留在应用私有目录,不会被删除按钮移除。
工程内素材
- setup.sql:可重复的建表与编号100示例。
- readings.csv:编号101、102,两条真实CSV样本。
安卓与鸿蒙使用相同SQL、参数与素材;鸿蒙系统连接/关闭是异步过程,工程以真实状态和返回值判断。数据库、备份路径来自组件与文件管理器的实际应用私有目录,未填写共享存储固定路径。
扫码添加客服咨询