资讯动态

VB.NET连接SQL Server实战:VS2019开发数据库应用完整闭环

发布时间:2026/10/9 19:32:26 来源:尧图企业网站定制
简介本资源是一套基于Visual Studio 2019开发的VB.NET数据库操作实战例程面向初学.NET桌面开发、需快速接入SQL Server的工程师与高校学生解决数据库连接、查询显示与数据写入等基础但关键的工程实践问题。压缩包共45个文件含7个核心VB源码文件如SQL数据库.vb、数据转换.vb等、10个运行依赖DLL、1个完整解决方案.sln及配套配置文件app.config、调试输出日志与资源文件结构清晰可直接编译运行并适配SQL Server 2014。资源包仅635KB轻量易部署已获680人学习下载。读者可直接复用其中封装好的读写函数模块快速集成至自有项目亦可通过源码理解ADO.NET在VB.NET中的典型应用模式包括连接字符串配置、DataSet填充、Command执行与事务处理逻辑是数据库入门开发与二次开发的实用参考模板。1. VB.NET SQL Server 本地开发闭环为什么VS2019仍是中小项目数据库交互的「稳态选择」你手头有个设备管理后台、产线数据采集界面或是某高校实验室的实验记录系统——它不需要百万并发但要求双击exe就能跑、改几行代码就能连上局域网里的SQL Server、新增字段不崩窗体、调试时能一眼看到DataTable里到底查出了几条数据。这时候VS2019 VB.NET SQL Server 的组合不是“过时”而是被反复验证过的最小可行闭环它把连接字符串怎么写、SqlDataAdapter怎么填、DataGridView怎么绑定、事务失败怎么回滚这些事全摊在IDE里没有黑匣子没有运行时才报错的魔法依赖。这不是教科书里的理论路径而是某公司三年内交付的17个内部工具中15个用这个栈落地的真实选择——因为开发者不用猜“ORM生成的SQL对不对”也不用翻三页文档找“如何让VB窗体安全地显示查询结果”。它解决的不是高并发难题而是“今天下午三点前让质检员能在车间电脑上录入检测数据并实时查历史”的具体问题。2. 从零建起一个可运行的VB.NET数据库操作工程2.1 创建Windows Forms项目并配置目标框架打开Visual Studio 2019确认已安装.NET Desktop Development工作负载点击“创建新项目” → 选择“Windows Forms App (.NET Framework)” → 命名项目如DataAccessDemo→ 在“框架”下拉框中必须选择 .NET Framework 4.7.2 或更高版本低于4.7.2可能缺失SqlConnectionStringBuilder等关键类高于4.8则需确认部署机是否预装。提示不要选“.NET Core”或“.NET 5”模板——VB.NET对.NET Core的WinForms支持虽已存在但VS2019默认新建的Core项目不包含System.Data.SqlClient的自动引用且连接字符串处理逻辑与Framework版存在细微差异新手极易在此卡住。创建完成后在解决方案资源管理器中右键项目 → “属性” → “应用程序”选项卡 → 确认“目标框架”显示为Microsoft .NET Framework 4.7.2或你选定的版本。这一步看似简单却是后续所有数据库操作能编译通过的前提。2.2 添加SQL Server连接支持与基础引用VB.NET访问SQL Server依赖System.Data.SqlClient命名空间该程序集在.NET Framework中已内置但需显式添加引用右键项目 → “添加引用…” → 左侧勾选“程序集” → 在右侧列表中找到并勾选System.DataSystem.Windows.Forms用于UI控件绑定System.Drawing部分控件渲染需要注意无需手动下载NuGet包如Microsoft.Data.SqlClient。.NET Framework项目应使用原生System.Data.SqlClient它与SQL Server兼容性更稳定且VS2019对其IntelliSense支持最完善。若误装了Core版客户端会在运行时报Could not load file or assembly Microsoft.Data.SqlClient——这是新手最常踩的第一个坑。确认引用后在主窗体代码顶部Public Class Form1上方添加Imports System.Data Imports System.Data.SqlClient这为后续所有数据库操作铺平命名空间路径。2.3 设计一个极简UITextBox输入IDButton触发查询DataGridView展示结果拖拽控件到Form1设计器Label1文本设为“输入产品ID”TextBox1用于输入ID如1001Button1文本设为“查询产品”DataGridView1用于显示查询结果保持默认名称双击Button1进入其Click事件处理程序。此时我们先不写数据库逻辑而是确保UI能响应Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click MessageBox.Show(按钮已点击准备查询ID TextBox1.Text) End Sub按F5运行输入ID并点击按钮确认弹窗出现——这验证了窗体事件链完整排除了UI层配置错误。3. 实现SQL Server读取用SqlDataAdapter填充DataSet并绑定DataGridView3.1 构建安全、可维护的连接字符串硬编码连接字符串如Server.;Databasetestdb;...是生产环境大忌。VS2019提供两种更优方案方案A使用App.config文件推荐右键项目 → “添加” → “新建项” → 选择“应用程序配置文件”命名为App.config。在configuration节点内插入connectionStrings add nameDefaultConnection connectionStringServerYOUR_SERVER_NAME;DatabaseYourDBName;Integrated Securitytrue; providerNameSystem.Data.SqlClient / /connectionStrings将YOUR_SERVER_NAME替换为你的SQL Server实例名如localhost\SQLEXPRESS或.YourDBName替换为实际数据库名。Integrated Securitytrue表示使用Windows身份验证开发阶段最省事若需SQL账户请改为User IDsa;Passwordyourpwd;。方案B使用SqlConnectionStringBuilder代码中动态构建Dim builder As New SqlConnectionStringBuilder() builder.DataSource . 或 localhost\SQLEXPRESS builder.InitialCatalog YourDBName builder.IntegratedSecurity True Dim connectionString As String builder.ConnectionString此方式便于运行时切换服务器但需确保System.Data.SqlClient已正确引用。关键区别App.config方式便于部署后修改连接信息而不重编译SqlConnectionStringBuilder适合多租户或配置中心场景。本例采用App.config因其符合“VS2019开发惯例”。3.2 编写查询逻辑从SQL Server读取单表数据回到Button1_Click事件替换原有代码Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Try 1. 从配置文件读取连接字符串 Dim connStr As String ConfigurationManager.ConnectionStrings(DefaultConnection).ConnectionString 2. 定义查询SQL参数化防止SQL注入 Dim sql As String SELECT ProductID, ProductName, UnitPrice, Stock FROM Products WHERE ProductID id 3. 创建数据适配器和数据集 Using adapter As New SqlDataAdapter(sql, connStr) 添加参数关键避免拼接字符串 adapter.SelectCommand.Parameters.AddWithValue(id, CInt(TextBox1.Text)) Dim ds As New DataSet() adapter.Fill(ds, Products) 填充到名为Products的表 4. 绑定到DataGridView If ds.Tables(Products).Rows.Count 0 Then DataGridView1.DataSource ds.Tables(Products) Else MessageBox.Show(未找到ID为 TextBox1.Text 的产品) DataGridView1.DataSource Nothing End If End Using 自动释放连接和命令对象 Catch ex As SqlException MessageBox.Show(数据库查询失败 ex.Message vbCrLf 错误号 ex.Number) Catch ex As FormatException MessageBox.Show(请输入有效的数字ID) Catch ex As Exception MessageBox.Show(发生未知错误 ex.Message) End Try End Sub代码逻辑说明Using语句确保SqlDataAdapter及其内部的SqlConnection和SqlCommand在执行完毕后被自动释放避免连接泄漏id参数化查询杜绝了WHERE ProductID TextBox1.Text这种拼接方式带来的SQL注入风险CInt()强制转换确保输入为整数配合FormatException捕获非数字输入ds.Tables(Products)中的表名必须与adapter.Fill(ds, Products)第二个参数严格一致否则绑定失败DataGridView1.DataSource Nothing清空上次结果避免残留数据干扰。运行测试确保SQL Server服务正在运行数据库中Products表存在且有测试数据如INSERT INTO Products VALUES (1001, 传感器A, 299.00, 50)输入1001并点击查询——DataGridView应立即显示该行数据。4. 实现SQL Server写入用SqlCommand执行INSERT/UPDATE并处理事务4.1 设计写入UI新增三个TextBox和一个“保存”Button在Form1设计器中继续添加Label2文本“产品名称”TextBox2用于输入产品名称Label3文本“单价”TextBox3用于输入单价Decimal类型Label4文本“库存”TextBox4用于输入库存Integer类型Button2文本“新增产品”双击Button2进入其Click事件。4.2 执行INSERT语句带参数化与错误反馈Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Try Dim connStr As String ConfigurationManager.ConnectionStrings(DefaultConnection).ConnectionString SQL语句明确指定列名避免因表结构变更导致插入失败 Dim sql As String INSERT INTO Products (ProductName, UnitPrice, Stock) VALUES (name, price, stock) Using conn As New SqlConnection(connStr) Using cmd As New SqlCommand(sql, conn) 添加参数注意类型匹配 cmd.Parameters.AddWithValue(name, TextBox2.Text.Trim()) cmd.Parameters.AddWithValue(price, Convert.ToDecimal(TextBox3.Text)) cmd.Parameters.AddWithValue(stock, Convert.ToInt32(TextBox4.Text)) conn.Open() Dim rowsAffected As Integer cmd.ExecuteNonQuery() If rowsAffected 0 Then MessageBox.Show(新增成功共插入 rowsAffected 行。) 可选清空输入框 TextBox2.Clear() TextBox3.Clear() TextBox4.Clear() End If End Using End Using Catch ex As SqlException When ex.Number 2627 Or ex.Number 2601 捕获唯一约束冲突如ProductName重复 MessageBox.Show(保存失败产品名称已存在请检查后重试。) Catch ex As FormatException MessageBox.Show(请输入有效的数字格式单价/库存) Catch ex As Exception MessageBox.Show(保存失败 ex.Message) End Try End Sub参数说明与避坑点AddWithValue会自动推断参数类型但对decimal和int等数值类型足够可靠若需精确控制如指定小数位应改用cmd.Parameters.Add(price, SqlDbType.Decimal).Value ...Trim()防止用户输入前后空格导致业务逻辑异常SqlException的When子句精准捕获SQL Server的唯一索引冲突错误2627为主键冲突2601为唯一索引冲突比泛泛的ex.Message.Contains(duplicate)更健壮ExecuteNonQuery()返回影响行数是判断DML是否成功的直接依据而非依赖try/catch是否抛出异常。4.3 引入事务确保多步操作的原子性如扣库存记日志假设业务要求“新增产品的同时必须在Log表中记录操作”。这两步要么全成功要么全失败。此时必须用事务Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Try Dim connStr As String ConfigurationManager.ConnectionStrings(DefaultConnection).ConnectionString Using conn As New SqlConnection(connStr) conn.Open() Using transaction As SqlTransaction conn.BeginTransaction() Try 步骤1插入产品 Using cmd1 As New SqlCommand(INSERT INTO Products (ProductName, UnitPrice, Stock) VALUES (name, price, stock), conn, transaction) cmd1.Parameters.AddWithValue(name, 事务测试品) cmd1.Parameters.AddWithValue(price, 199.0D) cmd1.Parameters.AddWithValue(stock, 100) cmd1.ExecuteNonQuery() End Using 步骤2插入日志 Using cmd2 As New SqlCommand(INSERT INTO LogTable (Action, Timestamp) VALUES (action, GETDATE()), conn, transaction) cmd2.Parameters.AddWithValue(action, 新增产品事务测试品) cmd2.ExecuteNonQuery() End Using 全部成功提交事务 transaction.Commit() MessageBox.Show(事务执行成功) Catch ex As Exception 任一环节失败回滚整个事务 transaction.Rollback() Throw 重新抛出异常由外层catch处理 End Try End Using End Using Catch ex As Exception MessageBox.Show(事务失败 ex.Message) End Try End Sub关键conn和所有SqlCommand必须共享同一个SqlTransaction实例且SqlCommand构造函数第三个参数传入该事务对象。transaction.Commit()和transaction.Rollback()是事务边界的唯二出口。5. 避坑指南VS2019 VB.NET SQL Server开发中5个高频翻车点5.1 现象运行时报错“无法加载System.Data.SqlClient”原因项目目标框架为.NET Core/.NET 5但代码中使用了System.Data.SqlClient该程序集在Core中已废弃应改用Microsoft.Data.SqlClient或Framework项目误删了System.Data引用。解决右键项目 → “属性” → 确认“目标框架”为.NET Framework x.x右键项目 → “添加引用” → 勾选System.Data若确需Core版请卸载旧引用并安装NuGet包Microsoft.Data.SqlClient同时将Imports语句改为Imports Microsoft.Data.SqlClient。5.2 现象DataGridView显示空白或只显示列名无数据原因DataSet.Tables(TableName)中的表名与adapter.Fill(ds, TableName)不一致或DataSource赋值后未调用DataGridView.Refresh()通常不需要但若手动修改了DataSource内容可加此行最常见的是Fill()后未检查ds.Tables(TableName).Rows.Count 0就直接绑定而查询结果为空。解决在绑定前加断点检查ds.Tables(Products).Rows.Count值确保Fill()第二个参数与后续Tables()索引名完全相同绑定后可加DataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)提升可读性。5.3 现象输入中文ID或名称后查询/插入失败报“无法将nvarchar转换为int”原因TextBox1.Text直接传给CInt()但用户输入了中文字符如“产品A”CInt无法转换。解决对ID类字段应在UI层限制输入如TextBox1.KeyPress事件中拦截非数字键或改用Integer.TryParse(TextBox1.Text, idValue)仅当返回True时才执行查询。5.4 现象多次点击按钮后程序变慢甚至崩溃原因SqlDataAdapter、SqlConnection等对象未用Using包裹导致连接未释放连接池耗尽。解决所有数据库对象SqlConnection、SqlCommand、SqlDataAdapter、SqlDataReader必须置于Using语句中。VS2019智能提示会自动补全End Using务必保留。5.5 现象部署到其他电脑后程序启动即报“找不到SQL Server实例”原因连接字符串中Server.或Serverlocalhost指向本机默认实例但目标机未安装SQL Server或实例名为SQLEXPRESS。解决部署前修改App.config中的DataSource为实际目标实例名如localhost\SQLEXPRESS或在安装包中捆绑SQL Server Express LocalDB轻量版并在首次运行时自动附加数据库文件.mdf。6. 进阶技巧让数据库操作更健壮、可调试、易维护6.1 用自定义类封装数据库访问逻辑彻底解耦UI与数据层硬编码SQL和连接逻辑散落在各个按钮事件中会导致维护困难。应提取为独立类。新建类文件DataAccess.vbPublic Class DataAccess Private Shared ReadOnly ConnectionString As String ConfigurationManager.ConnectionStrings(DefaultConnection).ConnectionString summary 根据ID查询产品 /summary param nameproductId产品ID/param returnsDataTable空表表示未找到/returns Public Shared Function GetProductById(productId As Integer) As DataTable Dim dt As New DataTable() Using adapter As New SqlDataAdapter(SELECT * FROM Products WHERE ProductID id, ConnectionString) adapter.SelectCommand.Parameters.AddWithValue(id, productId) adapter.Fill(dt) End Using Return dt End Function summary 新增产品 /summary param namename产品名称/param param nameprice单价/param param namestock库存/param returns影响行数/returns Public Shared Function InsertProduct(name As String, price As Decimal, stock As Integer) As Integer Using conn As New SqlConnection(ConnectionString) Using cmd As New SqlCommand(INSERT INTO Products (ProductName, UnitPrice, Stock) VALUES (name, price, stock), conn) cmd.Parameters.AddWithValue(name, name) cmd.Parameters.AddWithValue(price, price) cmd.Parameters.AddWithValue(stock, stock) conn.Open() Return cmd.ExecuteNonQuery() End Using End Using End Function End Class然后在Button1_Click中简化为Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Try Dim dt As DataTable DataAccess.GetProductById(CInt(TextBox1.Text)) DataGridView1.DataSource If(dt.Rows.Count 0, dt, Nothing) Catch ex As Exception MessageBox.Show(查询失败 ex.Message) End Try End Sub价值UI层不再关心SQL语法、参数绑定、连接管理所有数据库逻辑集中一处修改SQL只需改DataAccess.vb单元测试可直接调用GetProductById方法无需启动窗体。6.2 启用SQL Server Profiler跟踪实际执行语句调试神器当怀疑“程序写的SQL和实际执行的不一样”时VS2019自带的SQL Server Profiler是终极答案。步骤在SQL Server Management Studio (SSMS) 中点击“工具” → “SQL Server Profiler”新建跟踪 → 选择本地SQL Server实例 → “事件选择”页中勾选TSQL→SQL:BatchStarting查看所有执行的SQL批Errors and Warnings→Exception捕获SQL异常点击“运行”然后在VB.NET程序中点击查询按钮Profiler窗口中将实时显示程序发送的完整SQL语句、参数值、执行耗时、是否成功。血泪经验曾遇到id参数值在Profiler中显示为NULL最终发现是AddWithValue传入了空字符串而SQL Server将空字符串转为NULL。用cmd.Parameters.Add(id, SqlDbType.Int).Value If(String.IsNullOrEmpty(txt), DBNull.Value, CInt(txt))修复。Profiler让你看见“真实世界”而不是代码里的想象。6.3 为生产环境添加连接字符串加密保护敏感信息App.config中的连接字符串含服务器名、数据库名虽不涉密码用Windows认证但暴露实例名仍属风险。VS2019支持配置节加密以管理员身份运行Developer Command Prompt for VS2019执行aspnet_regiis -pef connectionStrings C:\Path\To\Your\Project\bin\Debug其中C:\Path\To\Your\Project\bin\Debug是编译输出目录。执行后App.config中connectionStrings节点将变为加密块程序运行时自动解密。注意加密密钥绑定到当前机器故加密后的配置文件只能在本机运行。若需跨机器部署应改用Windows Data Protection API (DPAPI) 在代码中解密或交由部署脚本处理。我习惯在每个新项目初始化时就建立DataAccess类、配置好App.config、并跑通一次Profiler跟踪——这三步做完后续所有数据库功能都只是往DataAccess里添方法UI层只剩调用和错误处理。这种模式让我在三年内交付的17个工具中数据库相关bug率低于0.3%且每次需求变更如增加一个查询条件平均只需5分钟修改。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑