易语言数据库操作进阶:参数化查询、事务处理与通用组件封装

news2026/3/24 22:39:41
易语言数据库操作进阶参数化查询、事务处理与通用组件封装一、学习目标与重点学习目标1. 理解SQL注入的危害与参数化查询的原理2. 掌握内置Ado引擎与SQLite3的参数化查询方法防止SQL注入3. 学会使用事务处理BEGIN TRANSACTION/COMMIT/ROLLBACK保证数据一致性4. 掌握分页查询逻辑的封装支持Access/SQLite35. 学会多表关联查询INNER JOIN/LEFT JOIN/RIGHT JOIN的SQL语句编写与执行6. 掌握通用查询组件的封装提高代码复用性7. 通过真实案例个人通讯录管理系统的进阶优化巩固所学知识。⚠️学习重点参数化查询的参数类型匹配、事务处理的回滚条件判断、分页查询的 LIMIT/TOP 语法差异、多表关联查询的字段别名设置、通用查询组件的接口设计。二、SQL注入的危害与参数化查询的原理2.1 SQL注入的危害SQL注入SQL Injection是一种常见的网络攻击方式攻击者通过在用户输入框中输入恶意SQL语句片段导致程序执行的SQL语句发生变化从而实现非法操作如查询敏感数据、删除数据表、修改密码。❌SQL注入的例子假设程序的查询SQL语句是SELECT*FROM联系人表WHERE姓名LIKE%用户输入%如果攻击者输入张三;DROPTABLE联系人表;--那么程序执行的SQL语句会变成SELECT*FROM联系人表WHERE姓名LIKE%张三;DROPTABLE联系人表;--%这条SQL语句会先查询姓名包含“张三”的记录然后删除整个联系人表造成严重的数据损失。2.2 参数化查询的原理参数化查询Parameterized Query是一种防止SQL注入的有效方法它将用户输入的内容作为参数传递给SQL语句而不是直接拼接成SQL语句的一部分。SQL语句的结构在编译时就已经确定用户输入的内容只会被当作数据处理不会影响SQL语句的结构。三、内置Ado引擎的参数化查询3.1 使用精易模块的SQL助手组件推荐精易模块精易编程助手配套的支持库提供了封装好的SQL助手组件使用参数化查询非常简单。.版本 2 .支持库 spec .支持库 eDB .支持库 jyk .子程序 查询联系人_Ado参数化, , 公开 .参数 查询条件, 文本型, 可空, 查询条件支持姓名、电话的模糊搜索 .局部变量 SQL助手, 类SQL助手 精易模块的SQL助手组件 .局部变量 查询SQL语句, 文本型 .局部变量 字段索引, 整数型 .局部变量 表项索引, 整数型 .局部变量 字段值, 文本型 初始化SQL助手组件连接字符串已在全局变量中存储 SQL助手.初始化 (全局变量_Ado连接字符串, ) 构建参数化查询SQL语句 查询SQL语句 “SELECT 联系人ID, 姓名, 电话, 邮箱 FROM 联系人表 WHERE 11” .如果真 (查询条件 ≠ “”) 查询SQL语句 查询SQL语句 “ AND (姓名 LIKE ? OR 电话 LIKE ?)” 添加参数姓名的模糊搜索 SQL助手.添加参数 (“?”, “%” 查询条件 “%”, ) 添加参数电话的模糊搜索 SQL助手.添加参数 (“?”, “%” 查询条件 “%”, ) .如果真结束 查询SQL语句 查询SQL语句 “ ORDER BY 姓名 ASC” 执行查询 .局部变量 查询结果, 对象 查询结果 SQL助手.执行SQL语句 (查询SQL语句, ) 判断是否查询到数据 .如果 (查询结果.记录数量 0) 信息框 (“未查询到符合条件的数据”, 0, “提示”) 返回 () .如果结束 清空超级列表框 超级列表框_联系人.全部删除 () 遍历记录集并显示数据 查询结果.移到首记录 () 判断循环首 (查询结果.是否到记录尾 () 假) 插入新表项 表项索引 超级列表框_联系人.插入表项 (, , , , , ) 遍历所有字段并设置标题 计次循环首 (查询结果.字段数量, 字段索引) 读取字段值 .如果 (查询结果.字段 (字段索引 1).类型 12) 日期类型 字段值 到文本 (查询结果.字段 (字段索引 1).值) .否则 字段值 到文本 (查询结果.字段 (字段索引 1).值) .如果结束 设置标题 超级列表框_联系人.置标题 (表项索引, 字段索引 1, 字段值) 计次循环首结束 移到下一条记录 查询结果.移到下一条 () 判断循环尾 () 提示用户查询成功 信息框 (“查询成功共找到” 到文本 (查询结果.记录数量) “条记录”, 0, “提示”)3.2 直接使用Ado的Command对象如果不想使用精易模块也可以直接使用Ado的Command对象实现参数化查询。.版本 2 .支持库 eDB .子程序 查询联系人_AdoCommand参数化, , 公开 .参数 查询条件, 文本型, 可空, 查询条件支持姓名、电话的模糊搜索 .局部变量 Command对象, 对象, 静态 .局部变量 查询SQL语句, 文本型 .局部变量 查询结果, 对象, 静态 .局部变量 字段索引, 整数型 .局部变量 表项索引, 整数型 .局部变量 字段值, 文本型 初始化Command对象 .如果真 (Command对象.对象指针 0) Command对象.创建 (“ADODB.Command”, , ) Command对象.ActiveConnection 全局变量_Ado连接组件 Command对象.CommandType 1 文本命令 .如果真结束 构建参数化查询SQL语句 查询SQL语句 “SELECT 联系人ID, 姓名, 电话, 邮箱 FROM 联系人表 WHERE 11” .如果真 (查询条件 ≠ “”) 查询SQL语句 查询SQL语句 “ AND (姓名 LIKE ? OR 电话 LIKE ?)” 添加参数姓名的模糊搜索 Command对象.参数.添加 (“?”, 200, 1, 50, “%” 查询条件 “%”) 200adVarChar1adParamInput50长度 添加参数电话的模糊搜索 Command对象.参数.添加 (“?”, 200, 1, 20, “%” 查询条件 “%”) .如果真结束 查询SQL语句 查询SQL语句 “ ORDER BY 姓名 ASC” 设置Command对象的SQL语句 Command对象.CommandText 查询SQL语句 执行查询并获取结果集 查询结果 Command对象.执行 (, , 1) 1adCmdText 判断是否查询到数据 .如果 (查询结果.记录数量 0) 信息框 (“未查询到符合条件的数据”, 0, “提示”) 返回 () .如果结束 清空超级列表框 超级列表框_联系人.全部删除 () 遍历记录集并显示数据 查询结果.移到首记录 () 判断循环首 (查询结果.是否到记录尾 () 假) 插入新表项 表项索引 超级列表框_联系人.插入表项 (, , , , , ) 遍历所有字段并设置标题 计次循环首 (查询结果.字段数量, 字段索引) 读取字段值 .如果 (查询结果.字段 (字段索引 1).类型 12) 日期类型 字段值 到文本 (查询结果.字段 (字段索引 1).值) .否则 字段值 到文本 (查询结果.字段 (字段索引 1).值) .如果结束 设置标题 超级列表框_联系人.置标题 (表项索引, 字段索引 1, 字段值) 计次循环首结束 移到下一条记录 查询结果.移到下一条 () 判断循环尾 () 提示用户查询成功 信息框 (“查询成功共找到” 到文本 (查询结果.记录数量) “条记录”, 0, “提示”) 清除Command对象的参数 Command对象.参数.清除 ()四、SQLite3的参数化查询4.1 SQLite3的参数绑定方法SQLite3支持两种参数绑定方式命名参数使用参数名或:参数名如WHERE 姓名 LIKE name位置参数使用?如WHERE 姓名 LIKE ?。4.2 SQLite3位置参数的代码实现.版本 2 .支持库 spec .支持库 eGrid .子程序 查询联系人_SQLite3参数化, , 公开 .参数 查询条件, 文本型, 可空, 查询条件支持姓名、电话的模糊搜索 .局部变量 查询SQL语句, 文本型 .局部变量 查询结果集句柄, sqlite3_stmt .局部变量 准备结果, 整数型 .局部变量 查询结果, 整数型 .局部变量 字段索引, 整数型 .局部变量 表项索引, 整数型 .局部变量 字段值, 文本型 .局部变量 错误信息, 文本型 构建参数化查询SQL语句 查询SQL语句 “SELECT 联系人ID, 姓名, 电话, 邮箱 FROM 联系人表 WHERE 11” .如果真 (查询条件 ≠ “”) 查询SQL语句 查询SQL语句 “ AND (姓名 LIKE ? OR 电话 LIKE ?)” .如果真结束 查询SQL语句 查询SQL语句 “ ORDER BY 姓名 ASC” 准备SQL语句 准备结果 sqlite3_prepare_v2 (全局变量_SQLite3连接句柄, 查询SQL语句, -1, 查询结果集句柄, ) .如果 (准备结果 ≠ 0) 获取并输出错误信息 sqlite3_errmsg (全局变量_SQLite3连接句柄, 错误信息) 调试输出 (“准备SQL语句失败SQL”, 查询SQL语句, “ 错误信息”, 错误信息) 信息框 (“准备SQL语句失败” 错误信息, 0, “错误”) sqlite3_free (取指针地址 (错误信息)) return () .如果结束 绑定参数 .如果真 (查询条件 ≠ “”) 绑定第一个参数姓名的模糊搜索UTF-8编码 sqlite3_bind_text (查询结果集句柄, 1, 到字节集 (“%” 查询条件 “%”), 取字节集长度 (“%” 查询条件 “%”), 0) 绑定第二个参数电话的模糊搜索UTF-8编码 sqlite3_bind_text (查询结果集句柄, 2, 到字节集 (“%” 查询条件 “%”), 取字节集长度 (“%” 查询条件 “%”), 0) .如果真结束 清空超级列表框 超级列表框_联系人.全部删除 () 执行查询并遍历结果集 查询结果 sqlite3_step (查询结果集句柄) 判断循环首 (查询结果 100) 100SQLITE_ROW表示查询到一条记录 插入新表项 表项索引 超级列表框_联系人.插入表项 (, , , , , ) 遍历所有字段并设置标题 计次循环首 (sqlite3_column_count (查询结果集句柄), 字段索引) 读取字段值根据字段类型读取 .局部变量 字段类型, 整数型 字段类型 sqlite3_column_type (查询结果集句柄, 字段索引 1) .如果 (字段类型 1) 整数型 字段值 到文本 (sqlite3_column_int (查询结果集句柄, 字段索引 1)) .否则 .如果 (字段类型 2) 双精度小数型 字段值 到文本 (取小数位 (sqlite3_column_double (查询结果集句柄, 字段索引 1), 2)) .否则 .如果 (字段类型 3) 文本型 .局部变量 文本指针, 整数型 文本指针 sqlite3_column_text (查询结果集句柄, 字段索引 1) .如果真 (文本指针 ≠ 0) 字段值 指针到文本 (文本指针, , #编码_UTF_8) .如果真结束 .如果结束 .如果结束 .如果结束 设置标题 超级列表框_联系人.置标题 (表项索引, 字段索引 1, 字段值) 计次循环首结束 移到下一条记录 查询结果 sqlite3_step (查询结果集句柄) 判断循环尾 () 释放查询结果集句柄 sqlite3_finalize (查询结果集句柄) 提示用户查询成功 信息框 (“查询成功共找到” 到文本 (超级列表框_联系人.取表项数 ()) “条记录”, 0, “提示”)五、事务处理保证数据一致性5.1 事务处理的基本概念事务Transaction是一组不可分割的数据库操作这些操作要么全部成功要么全部失败。事务处理的四个特性ACID原子性Atomicity事务中的所有操作要么全部执行要么全部回滚一致性Consistency事务执行前后数据库的状态必须保持一致隔离性Isolation事务之间相互隔离一个事务的执行不会影响其他事务的执行持久性Durability事务执行成功后对数据库的修改是永久的。5.2 事务处理的代码实现Ado引擎.版本 2 .支持库 spec .支持库 eDB .子程序 银行转账_Ado事务, , 公开 .参数 转出账户ID, 整数型, , 转出账户ID .参数 转入账户ID, 整数型, , 转入账户ID .参数 转账金额, 双精度小数型, , 转账金额 .局部变量 事务成功, 逻辑型 .局部变量 转出账户余额, 双精度小数型 .局部变量 转入账户余额, 双精度小数型 .局部变量 查询SQL语句, 文本型 .局部变量 更新SQL语句, 文本型 .局部变量 SQL助手, 类SQL助手 .局部变量 查询结果, 对象 初始化SQL助手组件 SQL助手.初始化 (全局变量_Ado连接字符串, ) 开启事务 SQL助手.开启事务 () 查询转出账户的当前余额 查询SQL语句 “SELECT 账户余额 FROM 银行账户表 WHERE 账户ID?” SQL助手.添加参数 (“?”, 转出账户ID, ) 查询结果 SQL助手.执行SQL语句 (查询SQL语句, ) 判断查询结果 .如果 (查询结果.记录数量 0) SQL助手.回滚事务 () 信息框 (“转出账户不存在”, 0, “错误”) return () .如果结束 转出账户余额 查询结果.字段 (“账户余额”).值 判断转出账户的余额是否足够 .如果 (转出账户余额 转账金额) SQL助手.回滚事务 () 信息框 (“转出账户余额不足当前余额¥” 到文本 (取小数位 (转出账户余额, 2)), 0, “错误”) return () .如果结束 查询转入账户的当前余额 SQL助手.清除参数 () 查询SQL语句 “SELECT 账户余额 FROM 银行账户表 WHERE 账户ID?” SQL助手.添加参数 (“?”, 转入账户ID, ) 查询结果 SQL助手.执行SQL语句 (查询SQL语句, ) 判断查询结果 .如果 (查询结果.记录数量 0) SQL助手.回滚事务 () 信息框 (“转入账户不存在”, 0, “错误”) return () .如果结束 转入账户余额 查询结果.字段 (“账户余额”).值 更新转出账户的余额 SQL助手.清除参数 () 更新SQL语句 “UPDATE 银行账户表 SET 账户余额? WHERE 账户ID?” SQL助手.添加参数 (“?”, 转出账户余额 - 转账金额, ) SQL助手.添加参数 (“?”, 转出账户ID, ) SQL助手.执行SQL语句 (更新SQL语句, ) 更新转入账户的余额 SQL助手.清除参数 () 更新SQL语句 “UPDATE 银行账户表 SET 账户余额? WHERE 账户ID?” SQL助手.添加参数 (“?”, 转入账户余额 转账金额, ) SQL助手.添加参数 (“?”, 转入账户ID, ) SQL助手.执行SQL语句 (更新SQL语句, ) 提交事务 SQL助手.提交事务 () 提示用户转账成功 信息框 (“转账成功转出账户ID” 到文本 (转出账户ID) “转入账户ID” 到文本 (转入账户ID) “转账金额¥” 到文本 (取小数位 (转账金额, 2)), 0, “提示”)5.3 事务处理的代码实现SQLite3.版本 2 .支持库 spec .子程序 银行转账_SQLite3事务, , 公开 .参数 转出账户ID, 整数型, , 转出账户ID .参数 转入账户ID, 整数型, , 转入账户ID .参数 转账金额, 双精度小数型, , 转账金额 .局部变量 事务成功, 逻辑型 .局部变量 转出账户余额, 双精度小数型 .局部变量 转入账户余额, 双精度小数型 .局部变量 查询SQL语句, 文本型 .局部变量 更新SQL语句, 文本型 .局部变量 查询结果集句柄, sqlite3_stmt .局部变量 准备结果, 整数型 .局部变量 查询结果, 整数型 .局部变量 执行结果, 整数型 .局部变量 错误信息, 文本型 开启事务 执行结果 sqlite3_exec (全局变量_SQLite3连接句柄, “BEGIN TRANSACTION;”, , , 错误信息) .如果 (执行结果 ≠ 0) 调试输出 (“开启事务失败错误信息”, 错误信息) 信息框 (“开启事务失败” 错误信息, 0, “错误”) sqlite3_free (取指针地址 (错误信息)) return () .如果结束 查询转出账户的当前余额 查询SQL语句 “SELECT 账户余额 FROM 银行账户表 WHERE 账户ID?” 准备结果 sqlite3_prepare_v2 (全局变量_SQLite3连接句柄, 查询SQL语句, -1, 查询结果集句柄, ) .如果 (准备结果 ≠ 0) 获取并输出错误信息 sqlite3_errmsg (全局变量_SQLite3连接句柄, 错误信息) 调试输出 (“准备查询转出账户余额的SQL语句失败SQL”, 查询SQL语句, “ 错误信息”, 错误信息) 信息框 (“准备查询转出账户余额的SQL语句失败” 错误信息, 0, “错误”) sqlite3_free (取指针地址 (错误信息)) 回滚事务 sqlite3_exec (全局变量_SQLite3连接句柄, “ROLLBACK;”, , , ) return () .如果结束 绑定参数 sqlite3_bind_int (查询结果集句柄, 1, 转出账户ID) 执行查询 查询结果 sqlite3_step (查询结果集句柄) .如果 (查询结果 ≠ 100) 获取并输出错误信息 sqlite3_errmsg (全局变量_SQLite3连接句柄, 错误信息) 调试输出 (“查询转出账户余额失败错误信息”, 错误信息) 信息框 (“查询转出账户余额失败” 错误信息, 0, “错误”) sqlite3_free (取指针地址 (错误信息)) 释放查询结果集句柄 sqlite3_finalize (查询结果集句柄) 回滚事务 sqlite3_exec (全局变量_SQLite3连接句柄, “ROLLBACK;”, , , ) return () .如果结束 读取转出账户的余额 转出账户余额 sqlite3_column_double (查询结果集句柄, 0) 释放查询结果集句柄 sqlite3_finalize (查询结果集句柄) 判断转出账户的余额是否足够 .如果 (转出账户余额 转账金额) 回滚事务 sqlite3_exec (全局变量_SQLite3连接句柄, “ROLLBACK;”, , , ) 信息框 (“转出账户余额不足当前余额¥” 到文本 (取小数位 (转出账户余额, 2)), 0, “错误”) return () .如果结束 查询转入账户的当前余额代码与查询转出账户类似此处省略 更新转出账户的余额 更新SQL语句 “UPDATE 银行账户表 SET 账户余额? WHERE 账户ID?” 准备结果 sqlite3_prepare_v2 (全局变量_SQLite3连接句柄, 更新SQL语句, -1, 查询结果集句柄, ) .如果 (准备结果 ≠ 0) 回滚事务等操作 return () .如果结束 sqlite3_bind_double (查询结果集句柄, 1, 转出账户余额 - 转账金额) sqlite3_bind_int (查询结果集句柄, 2, 转出账户ID) sqlite3_step (查询结果集句柄) sqlite3_finalize (查询结果集句柄) 更新转入账户的余额代码与更新转出账户类似此处省略 提交事务 sqlite3_exec (全局变量_SQLite3连接句柄, “COMMIT;”, , , ) 提示用户转账成功 信息框 (“转账成功转出账户ID” 到文本 (转出账户ID) “转入账户ID” 到文本 (转入账户ID) “转账金额¥” 到文本 (取小数位 (转账金额, 2)), 0, “提示”)六、分页查询逻辑的封装支持Access/SQLite36.1 Access的分页查询方法Access支持两种分页查询方法TOP方法适合简单分页先查询前N条记录再查询后M条记录ADO的PageSize/PageCount属性适合复杂分页通过设置记录集的PageSize属性来实现分页。6.2 SQLite3的分页查询方法SQLite3使用LIMIT M OFFSET N语法实现分页其中M每页显示的记录数N跳过的记录数(当前页码 - 1) × 每页显示的记录数。6.3 通用分页查询组件的封装.版本 2 .支持库 spec .支持库 eDB .支持库 eGrid .支持库 jyk 通用分页查询组件 .程序集 通用分页查询组件 .程序集变量 数据库类型, 整数型, , 0Access1SQLite3 .程序集变量 每页显示记录数, 整数型, , 默认值为10 .程序集变量 当前页码, 整数型, , 默认值为1 .程序集变量 总记录数, 整数型, , 0 .程序集变量 总页数, 整数型, , 0 .程序集变量 查询SQL语句, 文本型, , 基础查询SQL语句 .程序集变量 SQL助手, 类SQL助手 精易模块的SQL助手组件 .子程序 初始化分页查询, , 公开 .参数 用户选择的数据库类型, 整数型, , 0Access1SQLite3 .参数 用户查询的基础SQL语句, 文本型, , 基础查询SQL语句不含LIMIT/TOP .参数 用户每页显示记录数, 整数型, , 默认值为10 .局部变量 连接字符串, 文本型 保存参数 数据库类型 用户选择的数据库类型 查询SQL语句 用户查询的基础SQL语句 每页显示记录数 用户每页显示记录数 当前页码 1 初始化SQL助手组件 .如果 (数据库类型 0) 连接字符串 全局变量_Ado连接字符串 .否则 SQLite3需要先打开数据库并初始化连接字符串 .如果真 (全局变量_SQLite3连接句柄 0) 信息框 (“SQLite3数据库未打开”, 0, “错误”) return () .如果真结束 连接字符串 “ProviderSQLite3;Data Source...” 实际连接字符串需要根据SQLite3的驱动修改 .如果结束 SQL助手.初始化 (连接字符串, ) 计算总记录数和总页数 计算总记录数和总页数 ().版本 2 .支持库 spec .支持库 eDB .支持库 jyk .子程序 计算总记录数和总页数, , 公开 .局部变量 总记录数SQL语句, 文本型 .局部变量 查询结果, 对象 .局部变量 查询结果集句柄, sqlite3_stmt .局部变量 准备结果, 整数型 .局部变量 查询结果, 整数型 .局部变量 错误信息, 文本型 构建查询总记录数的SQL语句 总记录数SQL语句 “SELECT COUNT(*) AS 总记录数 FROM (” 查询SQL语句 “) AS 临时表” 根据数据库类型执行查询 .如果 (数据库类型 0) Access 查询结果 SQL助手.执行SQL语句 (总记录数SQL语句, ) 总记录数 查询结果.字段 (“总记录数”).值 .否则 .如果 (数据库类型 1) SQLite3 准备SQL语句 准备结果 sqlite3_prepare_v2 (全局变量_SQLite3连接句柄, 总记录数SQL语句, -1, 查询结果集句柄, ) .如果 (准备结果 ≠ 0) sqlite3_errmsg (全局变量_SQLite3连接句柄, 错误信息) 调试输出 (“准备查询总记录数的SQL语句失败SQL”, 总记录数SQL语句, “ 错误信息”, 错误信息) sqlite3_free (取指针地址 (错误信息)) return () .如果结束 执行查询 查询结果 sqlite3_step (查询结果集句柄) .如果 (查询结果 100) 总记录数 sqlite3_column_int (查询结果集句柄, 0) .如果结束 释放查询结果集句柄 sqlite3_finalize (查询结果集句柄) .如果结束 .如果结束 计算总页数 .如果 (总记录数 0) 总页数 0 .否则 总页数 取整 (总记录数 / 每页显示记录数) 1 .如果结束七、多表关联查询INNER JOIN/LEFT JOIN/RIGHT JOIN7.1 多表关联查询的基本概念多表关联查询是指查询多个数据表中的数据并根据它们之间的关联字段进行连接。常见的关联类型INNER JOIN内连接只返回两个表中关联字段匹配的记录LEFT JOIN左连接返回左表中的所有记录以及右表中关联字段匹配的记录RIGHT JOIN右连接返回右表中的所有记录以及左表中关联字段匹配的记录FULL OUTER JOIN全外连接返回两个表中的所有记录但SQLite3和Access不支持。7.2 联系人表与分组表的内连接查询代码示例.版本 2 .支持库 spec .支持库 eDB .支持库 eGrid .支持库 jyk .子程序 查询联系人分组_内连接, , 公开 .局部变量 查询SQL语句, 文本型 .局部变量 查询结果, 对象 .局部变量 字段索引, 整数型 .局部变量 表项索引, 整数型 .局部变量 字段值, 文本型 构建内连接查询SQL语句 查询SQL语句 “SELECT 联系人表.联系人ID, 联系人表.姓名, 联系人表.电话, 分组表.分组名称 FROM 联系人表” 查询SQL语句 查询SQL语句 “ INNER JOIN 分组表 ON 联系人表.分组ID 分组表.分组ID” 查询SQL语句 查询SQL语句 “ ORDER BY 分组表.分组名称 ASC, 联系人表.姓名 ASC” 执行查询 查询结果 SQL助手.执行SQL语句 (查询SQL语句, ) 判断是否查询到数据 .如果 (查询结果.记录数量 0) 信息框 (“未查询到符合条件的数据”, 0, “提示”) return () .如果结束 清空超级列表框 超级列表框_联系人.全部删除 () 遍历记录集并显示数据 查询结果.移到首记录 () 判断循环首 (查询结果.是否到记录尾 () 假) 插入新表项 表项索引 超级列表框_联系人.插入表项 (, , , , , ) 遍历所有字段并设置标题 计次循环首 (查询结果.字段数量, 字段索引) 读取字段值 字段值 到文本 (查询结果.字段 (字段索引 1).值) 设置标题 超级列表框_联系人.置标题 (表项索引, 字段索引 1, 字段值) 计次循环首结束 移到下一条记录 查询结果.移到下一条 () 判断循环尾 () 提示用户查询成功 信息框 (“查询成功共找到” 到文本 (查询结果.记录数量) “条记录”, 0, “提示”)八、真实案例个人通讯录管理系统的进阶优化8.1 系统功能进阶优化在第28篇的基础上个人通讯录管理系统的进阶优化包括防止SQL注入所有查询、插入、更新、删除操作都使用参数化查询事务处理添加、删除、修改多个联系人时使用事务处理分页查询当联系人数量较多时使用分页查询分组查询添加分组管理功能支持按分组查询、添加、删除联系人多表关联联系人表与分组表进行内连接查询显示联系人所属的分组。8.2 系统核心代码实现参数化添加联系人.版本 2 .支持库 spec .支持库 eDB .支持库 jyk .子程序 添加联系人_参数化, , 公开 .参数 姓名, 文本型, , 姓名 .参数 电话, 文本型, , 电话 .参数 邮箱, 文本型, 可空, 邮箱可空 .参数 地址, 文本型, 可空, 地址可空 .参数 备注, 文本型, 可空, 备注可空 .参数 分组ID, 整数型, , 分组ID默认值为1未分组 .局部变量 插入SQL语句, 文本型 .局部变量 受影响行数, 整数型 构建参数化插入SQL语句 插入SQL语句 “INSERT INTO 联系人表 (姓名, 电话, 邮箱, 地址, 备注, 分组ID, 创建时间) VALUES (?, ?, ?, ?, ?, ?, ?)” 添加参数 SQL助手.清除参数 () SQL助手.添加参数 (“?”, 姓名, ) SQL助手.添加参数 (“?”, 电话, ) SQL助手.添加参数 (“?”, 邮箱, ) SQL助手.添加参数 (“?”, 地址, ) SQL助手.添加参数 (“?”, 备注, ) SQL助手.添加参数 (“?”, 分组ID, ) SQL助手.添加参数 (“?”, 取现行时间 (), ) 执行插入SQL语句 受影响行数 SQL助手.执行SQL语句 (插入SQL语句, ) 判断是否插入成功 .如果 (受影响行数 ≤ 0) 信息框 (“添加联系人失败错误信息” SQL助手.错误信息, 0, “错误”) return () .如果结束 刷新超级列表框 查询联系人_Ado参数化 (“”) 提示用户添加成功 信息框 (“添加联系人成功姓名” 姓名, 0, “提示”)九、总结本章总结本章主要介绍了易语言数据库操作进阶包括SQL注入的危害与参数化查询的原理、内置Ado引擎与SQLite3的参数化查询方法、事务处理保证数据一致性、分页查询逻辑的封装、多表关联查询的SQL语句编写与执行、通用查询组件的封装以及真实案例个人通讯录管理系统的进阶优化。⚠️注意事项在使用参数化查询时要确保参数类型与数据库字段类型匹配在使用事务处理时要及时添加错误处理避免事务未提交或未回滚在使用分页查询时要注意LIMIT/TOP语法的差异在使用多表关联查询时要注意关联字段的索引设置提高查询效率。✅学习成果通过本章的学习读者已经掌握了易语言数据库操作的进阶技术可以开发出具有数据安全、一致性高、性能好的软件为后续学习面向对象编程和多线程数据库操作奠定了坚实的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2445376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…