跳到主要内容易语言数据库应用开发:Access本地存储与MySQL远程管理实战 | 极客日志编程语言
易语言数据库应用开发:Access本地存储与MySQL远程管理实战
综述由AI生成易语言中使用Access和MySQL数据库进行应用开发的方法,涵盖数据库基础概念、连接方式、CRUD操作及常见问题解决策略,并通过一个商品库存管理系统实战案例展示了具体实现过程。
月亮邮递员28 浏览 六、易语言数据库应用开发:Access本地存储与MySQL远程管理实战
6.1 引言
前三章我们学习了易语言的组件库、本地数据持久化和网络通信编程,但在处理大量结构化数据(如用户信息、商品库存、订单记录)时,文件存储和内存管理的效率较低,且难以实现复杂的数据查询、统计和关联操作。数据库是专门用于管理结构化数据的软件系统,具有高效、稳定、安全和易于维护等优点。
易语言提供了丰富的数据库支持库,常用的有:
- ACCESS支持库(内置,无需额外安装):适合开发本地单机应用
- SQLite支持库(轻量级,单文件数据库):适合开发移动应用或轻量级桌面应用
- MySQL支持库(开源,关系型数据库):适合开发多用户网络应用
- SQL Server支持库(微软,大型关系型数据库):适合开发企业级应用
本章将重点讲解ACCESS本地存储和MySQL远程管理的使用方法,并完成一个'简易商品库存管理系统'实战案例,实现商品信息的CRUD(增删改查)操作、库存统计和数据导出功能。
6.1.1 学习目标
- 了解关系型数据库的基础概念(表、字段、记录、主键、外键、SQL语句)
- 掌握ACCESS数据库的创建、连接和操作方法
- 学会使用MySQL数据库的连接、查询、插入、更新、删除操作
- 综合运用所学知识,完成'简易商品库存管理系统'实战案例
- 掌握数据库应用开发的常见问题及解决方案(连接失败、SQL语句错误、数据类型不匹配等)
6.1.2 学习重点
- 数据库的设计规范(表结构设计、字段类型选择、主键约束)
- SQL语句的编写(SELECT、INSERT、UPDATE、DELETE、WHERE、ORDER BY、GROUP BY)
- 易语言数据库组件的使用(数据库连接组件、记录集组件)
- 数据绑定与显示(超级列表框绑定记录集)
- 库存管理系统的UI设计和业务逻辑实现
- 数据安全与备份
6.2 关系型数据库基础概念
在进行数据库应用开发之前,我们需要了解一些基础概念。
6.2.1 数据库相关术语
| 术语 | 含义 | 示例 |
|---|
| 表 | 存储数据的基本单元,由字段和记录组成 | 用户表(tb_user) |
| 字段 | 表的列,用于定义数据的类型和属性 | 姓名(name)、性别(gender)、年龄(age) |
| 记录 | 表的行,用于存储一条完整的数据 | 张三、男、25 |
| 主键 | 唯一标识一条记录的字段,不能重复且不为空 | 用户ID(user_id) |
| 外键 | 关联另一个表主键的字段,用于建立表间关系 | 商品分类ID(category_id)关联分类表的分类ID(category_id) |
| 索引 | 提高查询效率的结构,类似于书籍的目录 | 在商品名称(product_name)字段上建立索引 |
| SQL语句 | 操作数据库的标准语言,分为DDL、DML、DQL、DCL等 | SELECT * FROM tb_product WHERE product_price > 100 |
6.2.2 SQL语句分类
| 分类 | 含义 | 常用命令 |
|---|
| DDL(数据定义语言) | 用于创建、修改、删除数据库和表结构 | CREATE、ALTER、DROP |
| DML(数据操作语言) | 用于插入、更新、删除表中的数据 | INSERT、UPDATE、DELETE |
| DQL(数据查询语言) | 用于查询表中的数据 | SELECT、FROM、WHERE、ORDER BY、GROUP BY |
| DCL(数据控制语言) | 用于控制用户的访问权限 | GRANT、REVOKE |
6.3 ACCESS数据库应用开发
ACCESS数据库是微软Office套件中的一个组件,是一种桌面型关系型数据库,适合开发本地单机应用。
6.3.1 ACCESS支持库介绍
易语言的ACCESS支持库是内置的,无需额外安装,提供了以下常用组件:
- ACCESS数据库组件:用于连接和操作ACCESS数据库
- 记录集组件:用于存储和操作查询结果
6.3.2 创建ACCESS数据库
设计思路
创建一个简易的商品库存管理系统数据库,包含两张表:
- 商品分类表(tb_category):存储商品的分类信息
- 商品表(tb_product):存储商品的基本信息和库存信息,通过分类ID关联分类表
表结构设计
- 商品分类表(tb_category):
| 字段名 | 字段类型 | 长度/精度 | 主键 | 外键 | 允许空 | 备注 |
|---|
| category_id | 自动编号 | - | 是 | - | 否 | 分类ID,唯一标识 |
| category_name | 文本 | 50 | - | - | 否 | 分类名称 |
| category_desc | 备注 | - | - | - | 是 | 分类描述 |
| create_time | 日期/时间 | - | - | - | 否 | 创建时间 |
- 商品表(tb_product):
| 字段名 | 字段类型 | 长度/精度 | 主键 | 外键 | 允许空 | 备注 |
|---|
| product_id | 自动编号 | - | 是 | - | 否 | 商品ID,唯一标识 |
| product_name | 文本 | 100 | - | - | 否 | 商品名称 |
| product_price | 数字 | 双精度 | - | - | 否 | 商品价格 |
| product_stock | 数字 | 长整型 | - | - | 否 | 商品库存 |
| category_id | 数字 | 长整型 | - | 是 | 否 | 分类ID,关联tb_category表的category_id字段 |
| product_desc | 备注 | - | - | - | 是 | 商品描述 |
| create_time | 日期/时间 | - | - | - | 否 | 创建时间 |
| update_time | 日期/时间 | - | - | - | 是 | 更新时间 |
创建步骤
- 打开ACCESS软件,选择'空数据库',保存为'inventory.accdb'
- 按照表结构设计创建两张表
- 在tb_product表的category_id字段上添加外键约束,关联tb_category表的category_id字段
- 向tb_category表中插入一些分类数据,如'电子产品'、'服装鞋帽'、'食品饮料'等
- 向tb_product表中插入一些商品数据,如'iPhone 15 Pro'、'Adidas运动鞋'、'可口可乐'等
6.3.3 连接ACCESS数据库
代码示例
.版本 2
.支持库 spec
.支持库 eAccess
' ACCESS数据库路径(放在程序目录下)
.程序集变量 g_DbPath, 文本型
' ACCESS数据库连接组件
.程序集变量 g_DbConn, 类_数据库
.子程序 __启动窗口_创建完毕
' 初始化组件属性
_启动窗口.标题 = '简易商品库存管理系统'
_启动窗口.宽度 = 900
_启动窗口.高度 = 650
_启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2
_启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2
' 初始化数据库路径
g_DbPath = 取运行目录 () + '\inventory.accdb'
' 检查数据库是否存在,不存在则创建
.如果真 (文件是否存在 (g_DbPath) = #假)
信息框 ('数据库文件不存在!', 0, '错误提示')
返回 ()
.如果真结束
' 连接ACCESS数据库
.如果真 (g_DbConn.打开 (g_DbPath) = #假)
信息框 ('数据库连接失败!', 0, '错误提示')
返回 ()
.如果真结束
' 加载分类数据到组合框
加载分类数据 ()
' 加载商品数据到超级列表框
加载商品数据 ()
调试输出 ('ACCESS数据库连接成功!路径:', g_DbPath)
.子程序 __启动窗口_将要被销毁
' 关闭数据库连接
g_DbConn.关闭 ()
调试输出 ('ACCESS数据库连接已关闭!')
.子程序 加载分类数据
.局部变量 记录集, 类_记录集
' 查询tb_category表中的所有数据
记录集 = g_DbConn.查询 ('SELECT * FROM tb_category ORDER BY category_id ASC')
.如果真 (记录集.记录数量 = 0)
信息框 ('商品分类数据为空!', 0, '提示信息')
返回 ()
.如果真结束
' 加载到组合框cboCategory
cboCategory.项目.清除 ()
.判断循环首 (记录集.到记录尾 () = #假)
cboCategory.项目.加入 (记录集.读文本 ('category_name'))
' 保存分类ID到组合框的'附加数据'中
cboCategory.项目附加数据.加入 (到文本 (记录集.读整数 ('category_id')))
记录集.到下一条 ()
.判断循环尾 ()
' 关闭记录集
记录集.关闭 ()
调试输出 ('商品分类数据加载成功!数量:', cboCategory.项目数量)
.子程序 加载商品数据
.局部变量 记录集, 类_记录集
.局部变量 i, 整数型
' 查询tb_product表和tb_category表的关联数据
记录集 = g_DbConn.查询 ('SELECT p.product_id, p.product_name, c.category_name, p.product_price, p.product_stock, p.product_desc, p.create_time, p.update_time FROM tb_product p LEFT JOIN tb_category c ON p.category_id = c.category_id ORDER BY p.product_id ASC')
.如果真 (记录集.记录数量 = 0)
' 商品数据为空,清空超级列表框
lstProduct.全部删除 ()
返回 ()
.如果真结束
' 加载到超级列表框lstProduct
lstProduct.全部删除 ()
.判断循环首 (记录集.到记录尾 () = #假)
lstProduct.插入表项 (, )
' 填充列数据
lstProduct.置标题 (i, 0, 到文本 (记录集.读整数 ('product_id'))) ' 商品ID
lstProduct.置标题 (i, 1, 记录集.读文本 ('product_name')) ' 商品名称
lstProduct.置标题 (i, 2, 记录集.读文本 ('category_name')) ' 分类名称
lstProduct.置标题 (i, 3, 到文本 (记录集.读双精度 ('product_price'), , '0.00')) ' 商品价格
lstProduct.置标题 (i, 4, 到文本 (记录集.读整数 ('product_stock'))) ' 商品库存
lstProduct.置标题 (i, 5, 记录集.读文本 ('product_desc')) ' 商品描述
lstProduct.置标题 (i, 6, 到文本 (记录集.读日期 ('create_time'), , 'yyyy年MM月dd日 HH时mm分ss秒')) ' 创建时间
lstProduct.置标题 (i, 7, 到文本 (记录集.读日期 ('update_time'), , 'yyyy年MM月dd日 HH时mm分ss秒')) ' 更新时间
i = i + 1
记录集.到下一条 ()
.判断循环尾 ()
' 关闭记录集
记录集.关闭 ()
调试输出 ('商品数据加载成功!数量:', i)
6.3.4 操作ACCESS数据库(CRUD)
插入商品数据
.版本 2
.支持库 spec
.支持库 eAccess
.子程序 _btnAddProduct_被单击
.局部变量 SQL语句, 文本型
.局部变量 商品名称, 文本型
.局部变量 分类ID, 整数型
.局部变量 商品价格, 双精度
.局部变量 商品库存, 整数型
.局部变量 商品描述, 文本型
.局部变量 受影响行数, 整数型
' 检查输入是否为空
商品名称 = txtProductName.内容
.如果真 (商品名称 = '')
信息框 ('请输入商品名称!', 0, '错误提示')
返回 ()
.如果真结束
分类ID = 到数值 (cboCategory.项目附加数据 [cboCategory.现行选中项])
.如果真 (分类ID = -1)
信息框 ('请选择商品分类!', 0, '错误提示')
返回 ()
.如果真结束
商品价格 = 到数值 (txtProductPrice.内容)
.如果真 (商品价格 < 0)
信息框 ('商品价格不能小于0!', 0, '错误提示')
返回 ()
.如果真结束
商品库存 = 到数值 (txtProductStock.内容)
.如果真 (商品库存 < 0)
信息框 ('商品库存不能小于0!', 0, '错误提示')
返回 ()
.如果真结束
商品描述 = edtProductDesc.内容
' 构建SQL插入语句
SQL语句 = 'INSERT INTO tb_product (product_name, category_id, product_price, product_stock, product_desc, create_time, update_time) VALUES ('' + 替换文本 (商品名称, ''", '''') + "', " + 到文本 (分类ID) + ", " + 到文本 (商品价格) + ", " + 到文本 (商品库存) + ", '" + 替换文本 (商品描述, "'", "''") + "', #" + 到文本 (取现行时间 (), , "yyyy-MM-dd HH:mm:ss") + "#, #" + 到文本 (取现行时间 (), , "yyyy-MM-dd HH:mm:ss") + "#)"
' 执行SQL语句
受影响行数 = g_DbConn.执行SQL (SQL语句)
.如果真 (受影响行数 = -1)
信息框 ('商品数据插入失败!错误信息:' + g_DbConn.取错误信息 (), 0, '错误提示')
返回 ()
.如果真结束
' 刷新商品数据
加载商品数据 ()
' 清空输入框
清空输入框 ()
信息框 ('商品数据插入成功!', 0, '成功提示')
调试输出 ('商品数据插入成功!受影响行数:', 受影响行数)
.子程序 替换文本, 文本型
.参数 原文本, 文本型
.参数 旧文本, 文本型
.参数 新文本, 文本型
' 替换文本中的单引号(SQL注入防护)
返回 (子文本替换 (原文本, 旧文本, 新文本, , , 真))
.子程序 清空输入框
' 清空输入框
txtProductName.内容 = ''
cboCategory.现行选中项 = -1
txtProductPrice.内容 = '0.00'
txtProductStock.内容 = '0'
edtProductDesc.内容 = ''
更新商品数据
.版本 2
.支持库 spec
.支持库 eAccess
.子程序 _btnUpdateProduct_被单击
.局部变量 SQL语句, 文本型
.局部变量 商品ID, 整数型
.局部变量 商品名称, 文本型
.局部变量 分类ID, 整数型
.局部变量 商品价格, 双精度
.局部变量 商品库存, 整数型
.局部变量 商品描述, 文本型
.局部变量 受影响行数, 整数型
' 检查是否选中了商品
.如果真 (lstProduct.现行选中项 = -1)
信息框 ('请选择要修改的商品!', 0, '错误提示')
返回 ()
.如果真结束
' 获取选中商品的ID
商品ID = 到数值 (lstProduct.置标题 (lstProduct.现行选中项, 0))
' 检查输入是否为空
商品名称 = txtProductName.内容
.如果真 (商品名称 = '')
信息框 ('请输入商品名称!', 0, '错误提示')
返回 ()
.如果真结束
分类ID = 到数值 (cboCategory.项目附加数据 [cboCategory.现行选中项])
.如果真 (分类ID = -1)
信息框 ('请选择商品分类!', 0, '错误提示')
返回 ()
.如果真结束
商品价格 = 到数值 (txtProductPrice.内容)
.如果真 (商品价格 < 0)
信息框 ('商品价格不能小于0!', 0, '错误提示')
返回 ()
.如果真结束
商品库存 = 到数值 (txtProductStock.内容)
.如果真 (商品库存 < 0)
信息框 ('商品库存不能小于0!', 0, '错误提示')
返回 ()
.如果真结束
商品描述 = edtProductDesc.内容
' 构建SQL更新语句
SQL语句 = 'UPDATE tb_product SET product_name = '' + 替换文本 (商品名称, ''", '''') + "', category_id = " + 到文本 (分类ID) + ", product_price = " + 到文本 (商品价格) + ", product_stock = " + 到文本 (商品库存) + ", product_desc = '" + 替换文本 (商品描述, "'", "''") + "', update_time = #" + 到文本 (取现行时间 (), , "yyyy-MM-dd HH:mm:ss") + "# WHERE product_id = " + 到文本 (商品ID)
' 执行SQL语句
受影响行数 = g_DbConn.执行SQL (SQL语句)
.如果真 (受影响行数 = -1)
信息框 ('商品数据更新失败!错误信息:' + g_DbConn.取错误信息 (), 0, '错误提示')
返回 ()
.如果真结束
' 刷新商品数据
加载商品数据 ()
' 清空输入框
清空输入框 ()
信息框 ('商品数据更新成功!', 0, '成功提示')
调试输出 ('商品数据更新成功!受影响行数:', 受影响行数)
删除商品数据
.版本 2
.支持库 spec
.支持库 eAccess
.子程序 _btnDeleteProduct_被单击
.局部变量 SQL语句, 文本型
.局部变量 商品ID, 整数型
.局部变量 受影响行数, 整数型
' 检查是否选中了商品
.如果真 (lstProduct.现行选中项 = -1)
信息框 ('请选择要删除的商品!', 0, '错误提示')
返回 ()
.如果真结束
' 获取选中商品的ID
商品ID = 到数值 (lstProduct.置标题 (lstProduct.现行选中项, 0))
' 确认删除
.如果真 (信息框 ('确定要删除该商品吗?删除后无法恢复!', 1, '确认删除') = #取消钮)
返回 ()
.如果真结束
' 构建SQL删除语句
SQL语句 = 'DELETE FROM tb_product WHERE product_id = " + 到文本 (商品ID)
' 执行SQL语句
受影响行数 = g_DbConn.执行SQL (SQL语句)
.如果真 (受影响行数 = -1)
信息框 ('商品数据删除失败!错误信息:' + g_DbConn.取错误信息 (), 0, '错误提示')
返回 ()
.如果真结束
' 刷新商品数据
加载商品数据 ()
' 清空输入框
清空输入框 ()
信息框 ('商品数据删除成功!', 0, '成功提示')
调试输出 ('商品数据删除成功!受影响行数:', 受影响行数)
查询商品数据
.版本 2
.支持库 spec
.支持库 eAccess
.子程序 _btnQueryProduct_被单击
.局部变量 SQL语句, 文本型
.局部变量 查询条件, 文本型
.局部变量 记录集, 类_记录集
.局部变量 i, 整数型
' 构建查询条件
查询条件 = ''
.如果真 (txtQueryName.内容 ≠ '')
查询条件 = 查询条件 + " AND p.product_name LIKE '%" + 替换文本 (txtQueryName.内容, "'", "''") + "%'"
.如果真结束
.如果真 (cboQueryCategory.现行选中项 ≠ -1)
查询条件 = 查询条件 + " AND c.category_id = " + 到文本 (cboQueryCategory.项目附加数据 [cboQueryCategory.现行选中项])
.如果真结束
.如果真 (txtQueryMinPrice.内容 ≠ '')
查询条件 = 查询条件 + " AND p.product_price ≥ " + 替换文本 (txtQueryMinPrice.内容, "'", "''")
.如果真结束
.如果真 (txtQueryMaxPrice.内容 ≠ '')
查询条件 = 查询条件 + " AND p.product_price ≤ " + 替换文本 (txtQueryMaxPrice.内容, "'", "''")
.如果真结束
' 构建SQL查询语句
SQL语句 = 'SELECT p.product_id, p.product_name, c.category_name, p.product_price, p.product_stock, p.product_desc, p.create_time, p.update_time FROM tb_product p LEFT JOIN tb_category c ON p.category_id = c.category_id WHERE 1=1" + 查询条件 + " ORDER BY p.product_id ASC"
' 执行查询
记录集 = g_DbConn.查询 (SQL语句)
.如果真 (记录集.记录数量 = 0)
' 查询结果为空,清空超级列表框
lstProduct.全部删除 ()
返回 ()
.如果真结束
' 加载到超级列表框lstProduct
lstProduct.全部删除 ()
.判断循环首 (记录集.到记录尾 () = #假)
lstProduct.插入表项 (, )
' 填充列数据
lstProduct.置标题 (i, 0, 到文本 (记录集.读整数 ('product_id'))) ' 商品ID
lstProduct.置标题 (i, 1, 记录集.读文本 ('product_name')) ' 商品名称
lstProduct.置标题 (i, 2, 记录集.读文本 ('category_name')) ' 分类名称
lstProduct.置标题 (i, 3, 到文本 (记录集.读双精度 ('product_price'), , '0.00')) ' 商品价格
lstProduct.置标题 (i, 4, 到文本 (记录集.读整数 ('product_stock'))) ' 商品库存
lstProduct.置标题 (i, 5, 记录集.读文本 ('product_desc')) ' 商品描述
lstProduct.置标题 (i, 6, 到文本 (记录集.读日期 ('create_time'), , 'yyyy年MM月dd日 HH时mm分ss秒')) ' 创建时间
lstProduct.置标题 (i, 7, 到文本 (记录集.读日期 ('update_time'), , 'yyyy年MM月dd日 HH时mm分ss秒')) ' 更新时间
i = i + 1
记录集.到下一条 ()
.判断循环尾 ()
' 关闭记录集
记录集.关闭 ()
调试输出 ('商品数据查询成功!数量:', i)
统计商品数据
.版本 2
.支持库 spec
.支持库 eAccess
.子程序 _btnStatistic_被单击
.局部变量 SQL语句, 文本型
.局部变量 记录集, 类_记录集
.局部变量 总商品数, 整数型
.局部变量 总库存数, 整数型
.局部变量 平均价格, 双精度
.局部变量 总金额, 双精度
' 查询总商品数、总库存数、平均价格、总金额
SQL语句 = 'SELECT COUNT(*) AS total_products, SUM(product_stock) AS total_stock, AVG(product_price) AS avg_price, SUM(product_price * product_stock) AS total_amount FROM tb_product'
记录集 = g_DbConn.查询 (SQL语句)
' 读取统计结果
总商品数 = 记录集.读整数 ('total_products')
总库存数 = 记录集.读整数 ('total_stock')
平均价格 = 记录集.读双精度 ('avg_price')
总金额 = 记录集.读双精度 ('total_amount')
' 关闭记录集
记录集.关闭 ()
' 显示统计结果
lblTotalProducts.标题 = '总商品数:' + 到文本 (总商品数) + ' 种'
lblTotalStock.标题 = '总库存数:' + 到文本 (总库存数) + ' 件'
lblAvgPrice.标题 = '平均价格:' + 到文本 (平均价格, , '0.00') + ' 元'
lblTotalAmount.标题 = '总金额:' + 到文本 (总金额, , '0.00') + ' 元'
调试输出 ('商品数据统计成功!总商品数:", 总商品数, " 种,总库存数:", 总库存数, " 件,平均价格:", 平均价格, " 元,总金额:", 总金额, " 元")
6.4 MySQL数据库应用开发
MySQL是一种开源的关系型数据库,适合开发多用户网络应用。
6.4.1 MySQL支持库介绍
易语言的MySQL支持库需要额外安装,常用的支持库有:
- 精易模块中的MySQL类:功能丰富,使用简单
- MySQL支持库1.1:官方或第三方开发的支持库
精易模块MySQL类安装
6.4.2 连接MySQL数据库
代码示例
.版本 2
.支持库 spec
.支持库 eMySQL
' MySQL数据库连接参数
.程序集变量 g_Host, 文本型, , 静态
.程序集变量 g_Port, 整数型, , 静态
.程序集变量 g_User, 文本型, , 静态
.程序集变量 g_Password, 文本型, , 静态
.程序集变量 g_Database, 文本型, , 静态
' MySQL数据库连接句柄
.程序集变量 g_Conn, 整数型, , 静态
.子程序 __启动窗口_创建完毕
' 初始化组件属性
_启动窗口.标题 = 'MySQL商品库存管理系统'
_启动窗口.宽度 = 900
_启动窗口.高度 = 650
_启动窗口.左边 = (取屏幕宽度 () - _启动窗口.宽度) ÷ 2
_启动窗口.顶边 = (取屏幕高度 () - _启动窗口.高度) ÷ 2
' 初始化连接参数(需要根据实际情况修改)
g_Host = 'localhost' ' 服务器IP地址,本地连接为localhost
g_Port = 3306 ' MySQL默认端口
g_User = 'root' ' 用户名,默认root
g_Password = '123456' ' 密码,需要根据实际情况修改
g_Database = 'inventory' ' 数据库名称
' 连接MySQL数据库
g_Conn = MySQL.连接 (g_Host, g_Port, g_User, g_Password, g_Database)
.如果真 (g_Conn = 0)
信息框 ('MySQL数据库连接失败!错误信息:' + MySQL.取错误信息 (g_Conn), 0, '错误提示')
返回 ()
.如果真结束
' 加载分类数据到组合框
加载分类数据 ()
' 加载商品数据到超级列表框
加载商品数据 ()
调试输出 ('MySQL数据库连接成功!')
.子程序 __启动窗口_将要被销毁
' 关闭MySQL数据库连接
MySQL.关闭连接 (g_Conn)
调试输出 ('MySQL数据库连接已关闭!')
.子程序 加载分类数据
.局部变量 SQL语句, 文本型
.局部变量 记录集, 类_记录集
.局部变量 i, 整数型
' 查询tb_category表中的所有数据
SQL语句 = 'SELECT * FROM tb_category ORDER BY category_id ASC'
记录集 = MySQL.查询 (g_Conn, SQL语句)
.如果真 (记录集.记录数量 = 0)
信息框 ('商品分类数据为空!', 0, '提示信息')
返回 ()
.如果真结束
' 加载到组合框cboCategory
cboCategory.项目.清除 ()
.判断循环首 (记录集.到记录尾 () = #假)
cboCategory.项目.加入 (记录集.读文本 ('category_name'))
' 保存分类ID到组合框的'附加数据'中
cboCategory.项目附加数据.加入 (到文本 (记录集.读整数 ('category_id')))
记录集.到下一条 ()
.判断循环尾 ()
' 关闭记录集
记录集.关闭 ()
调试输出 ('商品分类数据加载成功!数量:', cboCategory.项目数量)
.子程序 加载商品数据
.局部变量 SQL语句, 文本型
.局部变量 记录集, 类_记录集
.局部变量 i, 整数型
' 查询tb_product表和tb_category表的关联数据
SQL语句 = 'SELECT p.product_id, p.product_name, c.category_name, p.product_price, p.product_stock, p.product_desc, p.create_time, p.update_time FROM tb_product p LEFT JOIN tb_category c ON p.category_id = c.category_id ORDER BY p.product_id ASC'
记录集 = MySQL.查询 (g_Conn, SQL语句)
.如果真 (记录集.记录数量 = 0)
' 商品数据为空,清空超级列表框
lstProduct.全部删除 ()
返回 ()
.如果真结束
' 加载到超级列表框lstProduct
lstProduct.全部删除 ()
.判断循环首 (记录集.到记录尾 () = #假)
lstProduct.插入表项 (, )
' 填充列数据
lstProduct.置标题 (i, 0, 到文本 (记录集.读整数 ('product_id'))) ' 商品ID
lstProduct.置标题 (i, 1, 记录集.读文本 ('product_name')) ' 商品名称
lstProduct.置标题 (i, 2, 记录集.读文本 ('category_name')) ' 分类名称
lstProduct.置标题 (i, 3, 到文本 (记录集.读双精度 ('product_price'), , '0.00')) ' 商品价格
lstProduct.置标题 (i, 4, 到文本 (记录集.读整数 ('product_stock'))) ' 商品库存
lstProduct.置标题 (i, 5, 记录集.读文本 ('product_desc')) ' 商品描述
lstProduct.置标题 (i, 6, 到文本 (记录集.读日期 ('create_time'), , 'yyyy年MM月dd日 HH时mm分ss秒')) ' 创建时间
lstProduct.置标题 (i, 7, 到文本 (记录集.读日期 ('update_time'), , 'yyyy年MM月dd日 HH时mm分ss秒')) ' 更新时间
i = i + 1
记录集.到下一条 ()
.判断循环尾 ()
' 关闭记录集
记录集.关闭 ()
调试输出 ('商品数据加载成功!数量:', i)
6.4.3 操作MySQL数据库(CRUD)
MySQL数据库的操作方法与ACCESS类似,只是连接组件和记录集组件不同。
插入商品数据
.版本 2
.支持库 spec
.支持库 eMySQL
.子程序 _btnAddProduct_被单击
.局部变量 SQL语句, 文本型
.局部变量 商品名称, 文本型
.局部变量 分类ID, 整数型
.局部变量 商品价格, 双精度
.局部变量 商品库存, 整数型
.局部变量 商品描述, 文本型
.局部变量 受影响行数, 整数型
' 检查输入是否为空
商品名称 = txtProductName.内容
.如果真 (商品名称 = '')
信息框 ('请输入商品名称!', 0, '错误提示')
返回 ()
.如果真结束
分类ID = 到数值 (cboCategory.项目附加数据 [cboCategory.现行选中项])
.如果真 (分类ID = -1)
信息框 ('请选择商品分类!', 0, '错误提示')
返回 ()
.如果真结束
商品价格 = 到数值 (txtProductPrice.内容)
.如果真 (商品价格 < 0)
信息框 ('商品价格不能小于0!', 0, '错误提示')
返回 ()
.如果真结束
商品库存 = 到数值 (txtProductStock.内容)
.如果真 (商品库存 < 0)
信息框 ('商品库存不能小于0!', 0, '错误提示')
返回 ()
.如果真结束
商品描述 = edtProductDesc.内容
' 构建SQL插入语句
SQL语句 = 'INSERT INTO tb_product (product_name, category_id, product_price, product_stock, product_desc, create_time, update_time) VALUES ('' + 替换文本 (商品名称, ''", '''') + "', " + 到文本 (分类ID) + ", " + 到文本 (商品价格) + ", " + 到文本 (商品库存) + ", '" + 替换文本 (商品描述, "'", "''") + "', '" + 到文本 (取现行时间 (), , "yyyy-MM-dd HH:mm:ss") + "', '" + 到文本 (取现行时间 (), , "yyyy-MM-dd HH:mm:ss") + "')"
' 执行SQL语句
受影响行数 = MySQL.执行SQL (g_Conn, SQL语句)
.如果真 (受影响行数 = -1)
信息框 ('商品数据插入失败!错误信息:' + MySQL.取错误信息 (g_Conn), 0, '错误提示')
返回 ()
.如果真结束
' 刷新商品数据
加载商品数据 ()
' 清空输入框
清空输入框 ()
信息框 ('商品数据插入成功!', 0, '成功提示')
调试输出 ('商品数据插入成功!受影响行数:', 受影响行数)
6.5 简易商品库存管理系统实战
6.5.1 设计思路
- 商品分类管理:添加、修改、删除商品分类(本章省略,可自行扩展)
- 商品管理:添加、修改、删除、查询商品信息
- 库存管理:调整商品库存(本章省略,可自行扩展)
- 数据统计:统计总商品数、总库存数、平均价格、总金额
- 数据导出:将商品数据导出为CSV文件
6.5.2 创建工程与添加组件
- 创建一个新的Windows窗口程序工程
- 加载必要的支持库:系统核心支持库、ACCESS支持库(或精易模块)、扩展界面支持库一
- 添加以下组件:
- 标签组件:多个,分别用于显示'商品名称'、'商品分类'、'商品价格'、'商品库存'、'商品描述'、'查询条件'、'统计结果'
- 文本框组件:多个,分别用于输入商品名称、商品价格、商品库存、查询条件
- 编辑框组件:1个,用于输入商品描述
- 组合框组件:2个,分别用于选择商品分类和查询分类
- 超级列表框组件:1个,用于显示商品数据
- 按钮组件:多个,分别用于'添加商品'、'修改商品'、'删除商品'、'查询商品'、'统计数据'、'导出数据'、'清空输入'
- ACCESS数据库组件:1个,用于连接ACCESS数据库
6.5.3 设置组件属性
| 组件名称 | 属性名 | 属性值 |
|---|
| 标签1 | 标题 | 商品名称 |
| 标签1 | 名称 | lblProductName |
| 标签2 | 标题 | 商品分类 |
| 标签2 | 名称 | lblProductCategory |
| 标签3 | 标题 | 商品价格(元) |
| 标签3 | 名称 | lblProductPrice |
| 标签4 | 标题 | 商品库存(件) |
| 标签4 | 名称 | lblProductStock |
| 标签5 | 标题 | 商品描述 |
| 标签5 | 名称 | lblProductDesc |
| 标签6 | 标题 | 查询条件 |
| 标签6 | 名称 | lblQueryCondition |
| 标签7 | 标题 | 商品名称 |
| 标签7 | 名称 | lblQueryName |
| 标签8 | 标题 | 商品分类 |
| 标签8 | 名称 | lblQueryCategory |
| 标签9 | 标题 | 最低价格(元) |
| 标签9 | 名称 | lblQueryMinPrice |
| 标签10 | 标题 | 最高价格(元) |
| 标签10 | 名称 | lblQueryMaxPrice |
| 标签11 | 标题 | 统计结果 |
| 标签11 | 名称 | lblStatisticResult |
| 标签12 | 标题 | 总商品数:0 种 |
| 标签12 | 名称 | lblTotalProducts |
| 标签13 | 标题 | 总库存数:0 件 |
| 标签13 | 名称 | lblTotalStock |
| 标签14 | 标题 | 平均价格:0.00 元 |
| 标签14 | 名称 | lblAvgPrice |
| 标签15 | 标题 | 总金额:0.00 元 |
| 标签15 | 名称 | lblTotalAmount |
| 文本框1 | 名称 | txtProductName |
| 文本框1 | 内容 | |
| 文本框2 | 名称 | txtProductPrice |
| 文本框2 | 内容 | 0.00 |
| 文本框3 | 名称 | txtProductStock |
| 文本框3 | 内容 | 0 |
| 文本框4 | 名称 | txtQueryName |
| 文本框4 | 内容 | |
| 文本框5 | 名称 | txtQueryMinPrice |
| 文本框5 | 内容 | |
| 文本框6 | 名称 | txtQueryMaxPrice |
| 文本框6 | 内容 | |
| 编辑框1 | 名称 | edtProductDesc |
| 编辑框1 | 是否允许多行 | #真 |
| 编辑框1 | 滚动条 | #垂直滚动条 |
| 组合框1 | 名称 | cboCategory |
| 组合框1 | 项目 | |
| 组合框1 | 现行选中项 | -1 |
| 组合框2 | 名称 | cboQueryCategory |
| 组合框2 | 项目 | |
| 组合框2 | 现行选中项 | -1 |
| 超级列表框1 | 名称 | lstProduct |
| 超级列表框1 | 类型 | 报表列表框 |
| 超级列表框1 | 列数 | 8 |
| 超级列表框1 | 标题数组 | 商品ID,商品名称,商品分类,商品价格,商品库存,商品描述,创建时间,更新时间 |
| 超级列表框1 | 宽度数组 | 60,200,120,100,100,150,150,150 |
| 按钮1 | 名称 | btnAddProduct |
| 按钮1 | 标题 | 添加商品 |
| 按钮2 | 名称 | btnUpdateProduct |
| 按钮2 | 标题 | 修改商品 |
| 按钮2 | 禁止 | #真 |
| 按钮3 | 名称 | btnDeleteProduct |
| 按钮3 | 标题 | 删除商品 |
| 按钮3 | 禁止 | #真 |
| 按钮4 | 名称 | btnQueryProduct |
| 按钮4 | 标题 | 查询商品 |
| 按钮5 | 名称 | btnStatistic |
| 按钮5 | 标题 | 统计数据 |
| 按钮6 | 名称 | btnExportData |
| 按钮6 | 标题 | 导出数据 |
| 按钮7 | 名称 | btnClearInput |
| 按钮7 | 标题 | 清空输入 |
| ACCESS数据库组件1 | 名称 | dbConn |
6.5.4 编写代码
编写代码的过程与6.3.3和6.3.4类似,这里不再重复列出。
6.6 数据库应用开发常见问题与解决方案
6.6.1 数据库连接失败
问题现象:程序无法连接到数据库,提示'数据库连接失败'。
- 数据库文件不存在(ACCESS)
- 服务器IP地址或端口输入错误(MySQL)
- 用户名或密码错误(MySQL)
- 数据库名称错误(MySQL)
- 防火墙拦截了网络通信(MySQL)
- MySQL服务未启动(MySQL)
- 检查数据库文件路径是否正确(ACCESS)
- 检查服务器IP地址或端口输入是否正确(MySQL)
- 检查用户名或密码是否正确(MySQL)
- 检查数据库名称是否正确(MySQL)
- 关闭防火墙或添加防火墙例外(MySQL)
- 启动MySQL服务(MySQL)
6.6.2 SQL语句错误
问题现象:程序执行SQL语句时出错,提示'SQL语句错误'。
- SQL语句语法错误
- 字段名或表名拼写错误
- 数据类型不匹配
- SQL注入攻击(未处理单引号)
- 检查SQL语句语法是否正确
- 检查字段名或表名拼写是否正确
- 确保数据类型匹配
- 处理文本字段中的单引号(SQL注入防护)
6.6.3 数据类型不匹配
问题现象:程序读取或写入数据时出错,提示'数据类型不匹配'。
- 字段类型与读取/写入的数据类型不一致
- 字段长度不足
- 检查字段类型与读取/写入的数据类型是否一致
- 检查字段长度是否足够
6.6.4 数据导出错误
问题现象:程序导出数据时出错,提示'数据导出失败'。
- 检查导出路径是否存在
- 确保程序有写入权限
- 检查数据格式是否正确
6.7 总结
本章详细介绍了易语言数据库应用开发的基础概念和常用方法,包括ACCESS本地存储和MySQL远程管理。通过学习,我们掌握了:
- 关系型数据库的基础概念(表、字段、记录、主键、外键、SQL语句)
- ACCESS数据库的创建、连接和操作方法
- MySQL数据库的连接、查询、插入、更新、删除操作
- 综合运用所学知识,完成了'简易商品库存管理系统'实战案例
- 掌握了数据库应用开发的常见问题及解决方案
数据库应用开发是现代软件开发的重要环节,易语言提供了丰富的数据库支持库,让中文开发者能够快速上手。在实际开发中,还可以使用SQLite、SQL Server等其他数据库,或使用ORM框架简化数据库操作。
希望大家能够认真学习本章内容,多动手实践,理解关系型数据库的核心原理,为后续学习高级功能(如数据库优化、事务处理)打下坚实的基础。
相关免费在线工具
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
- JSON美化和格式化
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online