使用存储过程从ListBox批量插入数据时的重复插入异常问题排查
问题分析与修复方案
你遇到的重复插入、多选无效问题,根源在于两处关键代码错误,我帮你拆解并修正:
1. 错误的遍历对象
你当前循环的是ListBox1.SelectedValue,但这个属性在多选模式下只会返回第一个选中项的值;而且它是字符串类型,For Each会遍历该字符串的每个字符——这就导致:
- 选中单个项时,若ID是单字符(比如"5"),会触发1次循环,但结合第二个错误就变成插2次;若ID是多字符(比如"10"),会循环2次,插入两个错误的ID('1'和'0')。
- 选中多个项时,只会处理第一个选中项的值,其他项完全被忽略。
正确做法是遍历ListBox1.SelectedItems集合,它包含所有被选中的项。
2. 重复执行插入操作
你的代码里既调用了command.ExecuteNonQuery(),又调用了da.Fill(dst)——而存储过程是执行INSERT操作,ExecuteNonQuery()已经完成了插入,da.Fill()会再次执行该命令,导致每条记录被插入两次。插入操作完全不需要SqlDataAdapter和DataSet,直接用ExecuteNonQuery()就足够了。
修正后的后端代码
Protected Sub ass_postaDip() ' 遍历所有选中的项,替代错误的SelectedValue遍历 For Each selectedItem As ListItem In ListBox1.SelectedItems Dim cmdText As String = "Sp_ass_postaDip2" ' 从选中项的Value属性获取正确的ID Dim postaid As Integer = Int32.Parse(selectedItem.Value) Using Myconnection As New SqlConnection(SqlContConnStrinG), _ command As New SqlCommand(cmdText, Myconnection) Myconnection.Open() command.CommandType = CommandType.StoredProcedure ' 建议用SelectedValue获取员工ID,避免Text属性是显示名称而非ID的问题 command.Parameters.Add("@CodDip", SqlDbType.Int).Value = sel_dip.SelectedValue command.Parameters.Add("@CodPosta", SqlDbType.Int).Value = postaid command.Parameters.Add("@Data", SqlDbType.Date).Value = sel_data.Text ' 只执行一次插入操作,移除多余的DataAdapter和Fill逻辑 command.ExecuteNonQuery() ' Using块会自动关闭连接,无需手动调用Myconnection.Close() End Using Next End Sub
额外优化建议
- 存储过程里
from是SQL保留关键字,作为字段名必须用方括号包裹,同时建议开启SET NOCOUNT ON提升性能:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[Sp_ass_postaDip2] @CodDip int, @CodPosta int, @Data date AS BEGIN SET NOCOUNT ON; INSERT INTO postaDip (CODdip, CODposta, [from]) VALUES (@CodDip, @CodPosta, @Data); END
内容的提问来源于stack exchange,提问作者Tabboz
相关产品推荐
相关产品推荐

