C#医药销售管理系统源码解析:SQL Server 2000附加数据库与WinForms实战
简介这是一套面向高校计算机专业学生与C#初学者、WinForm开发者的医药销售管理系统完整源码工程可用于课程设计、毕业设计或自学练手帮助理解数据库驱动的桌面业务系统如何落地。压缩包共290个文件约2.49MB以78个cs源码文件、72个ico图标、72个resx资源文件及25个resources资源为主另含sln解决方案、csproj项目文件、sql建库脚本与mdf、ldf数据库文件结构完整可直接编译运行。数据库需采用SQL Server 2000将database文件夹中的MSMS_Data、MSMS_Log附加即可也可通过MSMS.sql导入建库系统管理员账号与密码均为8其余数据可进入系统或直接查询数据库获取。源码中可见药品查询、药品信息管理等模块适合对照学习窗体布局、数据绑定与增删改查实现思路。目前已有141人学习下载可作为医药销售类管理系统的参考模板。1. 从一份 C# 医药销售管理系统源码包说起SQL Server 2000 附加数据库就能跑如果你手头正好有一份基于 C# 的医药销售管理系统源码包解压后看到MSMS.csproj、YaoPinChaXun.cs、YaoPinXinXiGuanLi.cs这些文件第一反应大概率是「这玩意儿还能不能跑起来」。这份资源的核心价值在于它是一套完整的 WinForms 桌面应用覆盖了药品查询、药品信息管理、销售记录等医药流通场景的基础业务数据库层用的是 SQL Server 2000源码和数据库文件都打包在一起。它适合两类人一类是刚接触 C# 和数据库增删改查、想找一个真实业务系统练手的开发者另一类是手里有老系统维护需求、需要参考同类实现思路的从业者。需要提前说清楚的是SQL Server 2000 是这套系统的硬性依赖数据库文件MSMS_Data和MSMS_Log已经放在database文件夹里直接附加即可也可以用MSMS.sql脚本导入的方式创建。系统管理员账号是 8密码也是 8这个默认凭据在第一次登录时就会用到。整套代码没有花哨的架构就是典型的 WinForms ADO.NET 直连数据库正因为简单反而适合拿来拆解一个业务系统从建库到界面的完整链路。2. 环境搭建与数据库附加SQL Server 2000 的安装边界和替代方案2.1 为什么这套系统锁死了 SQL Server 2000先讲清楚一个现实问题SQL Server 2000 在 Windows 10/11 上直接安装的成功率很低常见做法是放在 Windows 7 虚拟机或者 Windows Server 2003/2008 环境里跑。这套系统之所以锁死 2000是因为它的数据库文件格式是 MDF/LDF 的早期版本高版本 SQL Server 虽然支持附加但附加后会自动升级数据库兼容级别一旦升级就回不去了。如果你只是想把系统跑起来看看效果用 SQL Server 2008 R2 或 2012 附加也能打开但要注意附加时不要勾选「升级」相关的选项否则原文件会被改写。更稳妥的做法是先把database文件夹整体复制一份备份再在副本上操作。另一个边界是连接字符串。这套源码里的连接配置大概率写的是Data Source.;Initial CatalogMSMS;User IDsa;Password...这种形式如果你本机的 SQL Server 实例名不是默认实例或者用了命名实例就需要改App.config或者代码里硬编码的连接串。常见做法是在App.config里加一个connectionStrings节点把连接串抽出来这样换环境时只改一处。2.2 附加数据库的两种路径图形界面和 T-SQL第一种路径是图形界面附加。打开 SQL Server 企业管理器2000或 SSMS高版本右键「数据库」→「附加」找到database文件夹下的MSMS_Data.MDF确认日志文件MSMS_Log.LDF路径正确点确定。如果提示「附加失败日志文件找不到」说明 MDF 和 LDF 不在同一目录或者文件名被改过需要手动指定 LDF 路径。第二种路径是用MSMS.sql脚本导入。这种方式更适合没有 MDF 文件或者想重建库的场景。操作步骤是先新建一个空数据库名字叫MSMS然后在查询窗口里打开MSMS.sql执行。注意脚本里可能包含CREATE DATABASE语句如果目标库已经存在会报错常见做法是把脚本开头的建库语句注释掉只保留建表和插入数据的部分。-- 如果 MSMS.sql 里包含建库语句先检查这一段 -- CREATE DATABASE MSMS -- ON PRIMARY (NAME NMSMS_Data, FILENAME ND:\database\MSMS_Data.MDF) -- LOG ON (NAME NMSMS_Log, FILENAME ND:\database\MSMS_Log.LDF) -- 如果目标库已存在把上面几行注释掉直接从 USE MSMS 开始执行 USE MSMS GO -- 建表语句示例药品信息表 CREATE TABLE YaoPinXinXi ( YaoPinID INT IDENTITY(1,1) PRIMARY KEY, YaoPinMingCheng NVARCHAR(100) NOT NULL, ShengChanChangJia NVARCHAR(200), PiZhunWenHao NVARCHAR(50), DanJia DECIMAL(10,2), KuCunLiang INT DEFAULT 0 ) GO这段 SQL 的逻辑是先切到MSMS库然后建一张药品信息表。IDENTITY(1,1)表示自增主键从 1 开始每次加 1NVARCHAR用于存储中文药品名称避免乱码DECIMAL(10,2)表示价格保留两位小数。参数上唯一需要根据实际情况改的是文件路径如果你把database文件夹放在了 D 盘脚本里的FILENAME就要对应改成 D 盘路径。2.3 连接字符串的配置和测试数据库附加好之后下一步是确认 C# 项目能连上。打开MSMS.csproj所在的解决方案找到App.config或者Settings.cs之类的配置文件。如果项目里没有独立的配置文件连接串可能直接写在某个DBHelper.cs或SqlHelper.cs里。常见做法是搜SqlConnection关键字定位到连接串所在位置。// 典型的连接串写法需要根据本机实例名和认证方式调整 string connStr Data Source.;Initial CatalogMSMS;Integrated SecurityTrue; // 如果用的是 SQL Server 身份验证改成 // string connStr Data Source.;Initial CatalogMSMS;User IDsa;Password你的密码; using (SqlConnection conn new SqlConnection(connStr)) { try { conn.Open(); Console.WriteLine(数据库连接成功); } catch (SqlException ex) { // 常见错误登录失败、实例名错误、TCP/IP 未启用 Console.WriteLine(连接失败 ex.Message); } }这段代码的作用是测试连接。Data Source.表示本机默认实例Integrated SecurityTrue表示用 Windows 身份验证不需要输账号密码。如果你用的是 sa 账号就换成User IDsa;Passwordxxx。测试时如果报「在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误」先检查 SQL Server 服务是否启动再检查 TCP/IP 协议是否在配置管理器里启用。SQL Server 2000 默认可能只开了命名管道需要手动开 TCP/IP。3. 源码结构拆解从 YaoPinChaXun.cs 看 WinForms 数据绑定3.1 药品查询模块的代码组织方式YaoPinChaXun.cs是药品查询窗体的代码文件配套的还有YaoPinChaXun.Designer.cs和YaoPinChaXun.resx。这种三文件结构是 WinForms 的标准做法.Designer.cs放界面控件的声明和布局.cs放业务逻辑.resx放资源。打开YaoPinChaXun.cs你会看到典型的 ADO.NET 查询流程构造SqlConnection、SqlDataAdapter、DataTable然后把DataTable绑定到DataGridView。// 药品查询按钮的点击事件 private void btnChaXun_Click(object sender, EventArgs e) { string keyword txtGuanJianZi.Text.Trim(); string sql SELECT YaoPinID, YaoPinMingCheng, ShengChanChangJia, DanJia, KuCunLiang FROM YaoPinXinXi WHERE 11; if (!string.IsNullOrEmpty(keyword)) { // 参数化查询避免 SQL 注入 sql AND (YaoPinMingCheng LIKE kw OR ShengChanChangJia LIKE kw); } using (SqlConnection conn new SqlConnection(connStr)) { SqlCommand cmd new SqlCommand(sql, conn); if (!string.IsNullOrEmpty(keyword)) { cmd.Parameters.AddWithValue(kw, % keyword %); } SqlDataAdapter adapter new SqlDataAdapter(cmd); DataTable dt new DataTable(); adapter.Fill(dt); dgvYaoPin.DataSource dt; } }这段代码的逻辑是先取用户输入的关键字拼一个基础查询语句如果关键字不为空就追加LIKE条件。Parameters.AddWithValue是参数化查询的写法能防止 SQL 注入比直接拼字符串安全。SqlDataAdapter.Fill把结果填充到DataTable再赋给DataGridView.DataSource界面就会自动显示数据。参数上需要注意的是LIKE的%要加在参数值里不能加在 SQL 字符串里否则参数化就失效了。3.2 药品信息管理模块的增删改查实现YaoPinXinXiGuanLi.cs对应的是药品信息管理窗体功能上比查询多出新增、修改、删除三个操作。这类窗体的典型布局是上方一个DataGridView显示列表下方一组TextBox和按钮用于编辑。新增操作的代码通常长这样// 新增药品信息 private void btnXinZeng_Click(object sender, EventArgs e) { string sql INSERT INTO YaoPinXinXi (YaoPinMingCheng, ShengChanChangJia, PiZhunWenHao, DanJia, KuCunLiang) VALUES (mingcheng, changjia, wenhao, danjia, kucun); using (SqlConnection conn new SqlConnection(connStr)) { SqlCommand cmd new SqlCommand(sql, conn); cmd.Parameters.AddWithValue(mingcheng, txtMingCheng.Text.Trim()); cmd.Parameters.AddWithValue(changjia, txtChangJia.Text.Trim()); cmd.Parameters.AddWithValue(wenhao, txtWenHao.Text.Trim()); cmd.Parameters.AddWithValue(danjia, decimal.Parse(txtDanJia.Text.Trim())); cmd.Parameters.AddWithValue(kucun, int.Parse(txtKuCun.Text.Trim())); conn.Open(); int rows cmd.ExecuteNonQuery(); if (rows 0) { MessageBox.Show(新增成功); // 刷新列表 BindData(); } } }这段代码的关键点是ExecuteNonQuery返回受影响行数大于 0 表示插入成功。参数化传值时要注意类型转换decimal.Parse和int.Parse如果遇到空字符串或非数字会抛异常常见做法是在界面上加Validating事件或者用decimal.TryParse做容错。删除操作通常是先取DataGridView当前行的YaoPinID然后执行DELETE FROM YaoPinXinXi WHERE YaoPinIDid。修改操作则是UPDATE语句配合WHERE条件。3.3 项目文件里的缓存文件要不要管解压后你会看到DesignTimeResolveAssemblyReferencesInput.cache、MSMS.csprojResolveAssemblyReference.cache、MSMS.csproj.GenerateResource.Cache这几个文件。它们不是源码是 Visual Studio 在编译和设计时生成的缓存可以安全删除不影响项目运行。MSMS.cdb是设计时数据库相关的缓存文件同样可以忽略。真正需要关注的是.csproj、.sln如果有、.cs和App.config。如果打开项目时提示「无法加载项目」先检查.csproj里引用的程序集路径是否存在常见做法是用文本编辑器打开.csproj看Reference节点里的HintPath是否指向了本机不存在的目录。4. 避坑与排查老系统在新环境下的五个血泪经验4.1 附加数据库时报「版本不兼容」现象用 SQL Server 2012 附加MSMS_Data.MDF时提示「数据库版本 539 无法打开此服务器支持 655 及更低版本」。原因SQL Server 2000 的数据库内部版本号是 539而 2012 支持的最低版本是 655高版本无法直接附加低版本文件。解决要么装 SQL Server 2008 R2 或更低版本要么用 SQL Server 2000 的sp_attach_db在 2000 环境里导出成 SQL 脚本再在高版本里执行脚本重建。4.2 登录时提示「sa 登录失败」现象用 sa 账号连数据库报「用户 sa 登录失败」。原因SQL Server 2000 安装时如果选了 Windows 身份验证模式sa 账号是禁用的。解决用 Windows 身份验证登录企业管理器在「安全性」→「登录」里找到 sa启用并设置密码然后重启 SQL Server 服务。如果用的是高版本 SQL Server还需要在「服务器属性」→「安全性」里把认证模式改成「SQL Server 和 Windows 身份验证模式」。4.3 中文药品名称显示成乱码现象DataGridView里药品名称显示为问号或方块。原因数据库字段用了VARCHAR而不是NVARCHAR或者连接串里没有指定字符集。解决把字段类型改成NVARCHAR连接串里加CharsetUTF-8或者确保 C# 端用SqlParameter传NVarChar类型。如果数据已经乱了需要重新导入。4.4 编译时报「找不到 MSMS.csproj 引用的程序集」现象打开解决方案后引用节点下出现黄色感叹号编译报「类型或命名空间不存在」。原因.csproj里引用的第三方 DLL 路径是原作者机器上的绝对路径你的机器上没有。解决删掉失效引用重新添加本机对应版本的 DLL。如果用的是系统程序集如System.Data.SqlClient检查目标框架版本是否匹配老项目通常是 .NET Framework 2.0 或 3.5需要在新版 Visual Studio 里装对应的开发包。4.5 查询按钮点了没反应现象输入关键字点查询DataGridView不刷新。原因可能是事件没绑定或者connStr变量为空导致连接没建立。解决在btnChaXun_Click第一行加断点看是否进入事件检查connStr是否在窗体加载时赋值检查dgvYaoPin.DataSource是否被重新赋值后没有调用Refresh。常见做法是在BindData()方法末尾加dgvYaoPin.Refresh()。5. 进阶用法把默认账号 8/8 改掉以及用 SQL 脚本做数据初始化5.1 修改系统管理员账号和密码系统默认管理员账号是 8密码也是 8这个凭据在MSMS.sql或者数据库的GuanLiYuan表里。要改的话有两种方式一是直接进数据库改二是改源码里的登录验证逻辑。直接改数据库更简单-- 查看当前管理员表 SELECT * FROM GuanLiYuan -- 修改账号和密码假设表里有 ZhangHao 和 MiMa 字段 UPDATE GuanLiYuan SET ZhangHao admin, MiMa newpassword WHERE ZhangHao 8执行前先确认表名和字段名不同版本的源码可能命名不一样。如果源码里登录验证是硬编码的比如if (txtZhangHao.Text 8 txtMiMa.Text 8)那就需要改代码重新编译。常见做法是搜8这个字符串定位到验证逻辑后改成从数据库查询。5.2 用 SQL 脚本批量初始化药品数据如果你不想手动一条条录入药品信息可以写一个批量插入脚本。假设YaoPinXinXi表已经建好可以这样批量插入-- 批量插入药品数据 INSERT INTO YaoPinXinXi (YaoPinMingCheng, ShengChanChangJia, PiZhunWenHao, DanJia, KuCunLiang) VALUES (N阿莫西林胶囊, N华北制药, N国药准字H13020765, 12.50, 100), (N布洛芬缓释胶囊, N中美史克, N国药准字H10900089, 18.00, 80), (N头孢克肟分散片, N广州白云山, N国药准字H20051234, 25.80, 60), (N维生素C片, N东北制药, N国药准字H21020765, 5.00, 200)这段脚本一次插入四条药品记录N前缀表示 Unicode 字符串确保中文不乱码。执行后可以在系统里直接查询到这些数据。参数上唯一要注意的是DanJia和KuCunLiang的类型要和表定义一致如果表里是DECIMAL(10,2)和INT这里的值就要对应。5.3 验证系统是否跑通的三个检查点第一个检查点是登录。用 8/8 登录如果能进主界面说明数据库连接和登录验证都通了。第二个检查点是查询。在药品查询界面输入「阿莫西林」如果能查出刚才插入的数据说明YaoPinChaXun.cs的查询逻辑和数据库表都对上了。第三个检查点是新增。在药品信息管理界面新增一条记录然后刷新列表看是否出现再进数据库SELECT确认数据落库。这三个点走完整套系统的核心链路就算验证通过了。从那以后我每次拿到这种老系统源码包都会先备份database文件夹再在虚拟机上装对应版本的 SQL Server最后才动源码。这套流程帮我省掉了至少三次「附加失败导致原库损坏」的后悔药。希望帮到你。本文还有配套的精品资源点击获取