当前位置: 首页 > article >正文

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

易语言数据库操作进阶参数化查询、事务处理与通用组件封装一、学习目标与重点学习目标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语法的差异在使用多表关联查询时要注意关联字段的索引设置提高查询效率。✅学习成果通过本章的学习读者已经掌握了易语言数据库操作的进阶技术可以开发出具有数据安全、一致性高、性能好的软件为后续学习面向对象编程和多线程数据库操作奠定了坚实的基础。

相关文章:

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

易语言数据库操作进阶:参数化查询、事务处理与通用组件封装一、学习目标与重点 💡学习目标:1. 理解SQL注入的危害与参数化查询的原理;2. 掌握内置Ado引擎与SQLite3的参数化查询方法(防止SQL注入)&#xff1…...

Qwen-Image-Lightning前端集成:JavaScript实现实时图像预览

Qwen-Image-Lightning前端集成:JavaScript实现实时图像预览 想象一下,你正在开发一个创意工具网站,用户输入一段文字描述,几秒钟后就能看到对应的图片慢慢“画”出来,整个过程流畅自然,还能看到生成进度。…...

保姆级教程:用Stream搞定iOS App抓包,从证书安装到数据查看一步不落

iOS应用数据抓包实战指南:从Stream配置到数据分析全解析 在移动应用开发和测试过程中,数据抓包是一项基础但至关重要的技能。无论是调试API接口、分析网络性能,还是排查数据异常,掌握专业的抓包技术都能显著提升工作效率。对于iOS…...

Apache HTTP Server 安全加固综合指南

好的,我们来聚焦于 Apache HTTP Server 的安全。这是一个非常广泛且重要的主题。我将为您提供一个结构化的、从基础到进阶的 Apache 安全加固指南,您可以将其视为一个“手动版”智能体的检查清单和操作手册。Apache HTTP Server 安全加固综合指南 一、 核…...

3大核心功能革新Apple Silicon Mac游戏体验:PlayCover全攻略

3大核心功能革新Apple Silicon Mac游戏体验:PlayCover全攻略 【免费下载链接】PlayCover Community fork of PlayCover 项目地址: https://gitcode.com/gh_mirrors/pl/PlayCover 还在为Apple Silicon Mac无法运行iOS游戏而困扰吗?PlayCover作为一…...

094华为黄大年茶思屋第3期·难题二:[高性能]数据库智能基数估计算法

华为黄大年茶思屋第3期难题二:[高性能]数据库智能基数估计算法 双思路解题方案:常规行业解法 本源动态原点解法,双框架对照,专家级可落地、可验证 核心亮点:直击数据库基数估计精度瓶颈,提供轻量化、自适应…...

墨语灵犀入门必看:Hunyuan-MT蒸馏版与全量版在古文翻译任务中的权衡

墨语灵犀入门必看:Hunyuan-MT蒸馏版与全量版在古文翻译任务中的权衡 1. 引言:当古典美学遇见AI翻译 想象一下这样的场景:你需要翻译一段深奥的古文,可能是唐诗宋词,也可能是先秦典籍。传统的翻译工具给你的是机械式的…...

093华为黄大年茶思屋第3期·难题一:AI大模型训练 – 多维度混合并行策略的自动搜索算法

华为黄大年茶思屋第3期难题一:AI大模型训练 – 多维度混合并行策略的自动搜索算法 双思路解题方案:常规行业解法 本源动态原点解法,双框架对照,专家级可落地、可验证 核心亮点:直击大模型并行策略搜索产业卡点&#x…...

智能微电网多目标优化:粒子群算法的完整数据运行与验证

智能微电网中利用粒子群算法实现多目标优化 有完整数据可运行 :智能微电网中对多目标问题的优化,采用粒子群的完美验证,有详细注释,可以借鉴 文件列表: C_buy2.txt C_sell2.txt C_sub2.txt fitnessEcoVir.m Load2.txt …...

Legacy iOS Kit终极指南:如何零成本复活旧iPhone与iPad设备

Legacy iOS Kit终极指南:如何零成本复活旧iPhone与iPad设备 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to downgrade/restore, save SHSH blobs, and jailbreak legacy iOS devices 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit L…...

嵌入式C++轻量工具库:零分配字符串与安全格式化

1. toolbox 库概述:面向嵌入式环境的轻量级通用工具集toolbox是一个专为资源受限嵌入式系统(尤其是 Arduino 风格平台)设计的通用工具库。它并非追求功能完备性,而是以确定性、低开销、内存可控为根本设计哲学,直面 MC…...

语音信号处理中的小波分解法降噪方法MATLAB例程

语音信号处理--降噪方法之小波分解法 MATLAB例程语音降噪这事儿,日常太刚需了——打电话时的背景杂音、录音里的环境噪音,都得想办法干掉。小波分解法算是语音降噪里的老牌选手了,比起傅里叶只能看全局频率,小波能同时抓时域和频域…...

Mbed OS下BLE鼠标HID服务开发指南

1. 项目概述Mbed BLE Mouse 是一个面向 Arduino 兼容开发板的蓝牙低功耗(BLE)人机接口设备(HID)库,专为运行 Mbed OS 的嵌入式平台设计。该库将具备 BLE 能力的微控制器(如 Arduino Nano 33 BLE、Nano 33 B…...

零门槛实战:Python百度搜索API从入门到精通

零门槛实战:Python百度搜索API从入门到精通 【免费下载链接】python-baidusearch 自己手写的百度搜索接口的封装,pip安装,支持命令行执行。Baidu Search unofficial API for Python with no external dependencies 项目地址: https://gitco…...

未来最有前景的行业及终身发展方向指南

未来最有前景的行业及终身发展方向指南根据最新行业趋势分析,以下5个行业不仅前景广阔,更适合作为终身职业发展方向,并附上具体实施步骤:一、人工智能与大模型应用为什么值得长期投入:国家"十五五"规划重点支…...

Python处理MDX词典数据实战:从解析到Excel导出完整流程

Python处理MDX词典数据实战:从解析到Excel导出完整流程 在语言学习和词典开发领域,MDX格式因其高效的压缩和检索能力成为主流词典存储格式之一。但对于需要批量分析或迁移数据的开发者而言,直接操作这种二进制文件始终是个技术门槛。本文将带…...

手把手教你用云测试平台搞定安卓/iOS/鸿蒙兼容性测试(含Testin/百度MTC实战)

云测试平台实战指南:零成本解决安卓/iOS/鸿蒙兼容性问题 当你的应用需要同时覆盖三大移动平台时,真机设备采购成本可能高达数十万元。去年我们团队上线一款社交应用时,仅购买主流测试设备就花掉了23万预算——直到发现云测试平台能以1/100的…...

25岁的Java工程师:我的AI转型之路,附完整学习路线与资料下载

一位Java开发者在AI大模型兴起后面临职业危机,通过博学谷的系统培训成功转型AI领域。经过6个月刻苦学习,在老师指导下克服数学基础薄弱等困难,最终获得月薪15K的AI工作机会。作者分享了自己的转型经历、完整学习路线和AI大模型资源&#xff0…...

SourceTree 合并提交实战:5分钟搞定零散提交的批量处理(附Cherry Pick技巧)

SourceTree高效提交管理:从零散提交到优雅合并的完整指南 在团队协作开发中,代码提交历史就像项目的日记本——杂乱无章的记录会让后续的维护和问题追踪变得异常困难。想象一下,当你需要回溯某个功能的开发过程时,面对几十个"…...

Anaconda3安装和安装pycharm(保姆级教程)

目录 一.安装Anaconda3 二.安装pycharm 三.设置配置(可选根据自己的习惯来) Anaconda3 与 PyCharm 介绍、安装及关系 Anaconda3 是一个集成了 Python 解释器、大量数据分析和机器学习常用库(如 numpy、pandas),还自带 conda 环境管理工具的…...

(理论篇)深入剖析认证崩溃——从弱口令到暴力破解

概述:在应用程序的安全防御体系中,身份认证是守卫系统大门的第一道关卡。这道关卡的失守,通常被称为“认证崩溃”。 攻击者通过利用认证或会话管理中的缺陷,能够成功破译密码、密钥或会话令牌,从而获得非授权访问权限。…...

RAW图像处理避坑指南:如何正确分离和组合RGGB四通道(Python版)

RAW图像处理避坑指南:如何正确分离和组合RGGB四通道(Python版) 第一次处理RAW图像时,我犯了一个低级错误——直接把RGGB四个通道当作普通的RGB图像来处理。结果生成的图像色彩完全错乱,红色变成了诡异的紫色&#xff0…...

ret2text Ctfhub

简单的栈溢出gets函数,v4,在ebp-0x70shiftF12先传入形参,因为是64位,可以查看是将sh写入rdi寄存器中,之后调用函数system将常量区的地址写入rdi寄存器中,之后对rdi进行寄存器间接寻址.rodata:字…...

CoPaw赋能物联网(IoT)后端开发:设备数据解析与告警规则生成

CoPaw赋能物联网(IoT)后端开发:设备数据解析与告警规则生成 1. 物联网开发的现实挑战 想象一下这样的场景:你刚接手一个大型物联网平台项目,需要接入上百种不同类型的设备。这些设备来自不同厂商,协议文档…...

Vue-Flow-Editor:用SVG魔法点亮你的流程图创作之旅

Vue-Flow-Editor:用SVG魔法点亮你的流程图创作之旅 【免费下载链接】vue-flow-editor Vue Svg 实现的flow可视化编辑器 项目地址: https://gitcode.com/gh_mirrors/vu/vue-flow-editor 想象一下,你正在设计一个复杂的业务流程,脑海中…...

windows下git使用教程2(gitee仓库与代码提交)

前序文章: windows下git使用教程1(安装与使用) 代码仓库gitee的使用 介绍了git的基础操作,这篇文章介绍一下远程仓库和代码提交的操作。 1.远程仓库 远程仓库是托管在网络服务器上的 Git 仓库,和你本地电脑上的 本…...

技术解密:LilToon卡通渲染着色器的模块化革命与跨平台实践指南

技术解密:LilToon卡通渲染着色器的模块化革命与跨平台实践指南 【免费下载链接】lilToon Feature-rich shaders for avatars 项目地址: https://gitcode.com/gh_mirrors/li/lilToon 在Unity实时渲染生态中,卡通渲染技术长期面临风格化与性能优化的…...

从知识概念预测到精准推送:构建下一代个性化习题推荐引擎

1. 为什么我们需要下一代习题推荐系统? 每次打开在线学习平台时,你是否遇到过这样的困扰:系统推荐的题目要么简单得像112,要么难到让你怀疑人生?更糟的是,反复出现的同类题型让你想摔键盘。这背后暴露的正是…...

仅限首批MCP认证伙伴内部流出:OAuth 2026架构设计图原始版(含签名链路、密钥轮转SOP与审计日志字段规范)

第一章:OAuth 2026架构设计图概览与MCP认证背景OAuth 2026 是下一代授权框架的演进标准,由 IETF OAuth Working Group 于 2025 年底正式发布,旨在应对零信任架构、跨域设备协同及量子安全过渡等新兴挑战。其核心创新在于将传统“客户端-资源服…...

espeak-ng语音合成终极指南:快速掌握127种语言免费TTS技术

espeak-ng语音合成终极指南:快速掌握127种语言免费TTS技术 【免费下载链接】espeak-ng espeak-ng: 是一个文本到语音的合成器,支持多种语言和口音,适用于Linux、Windows、Android等操作系统。 项目地址: https://gitcode.com/GitHub_Trendi…...