VB.NET中如何正确保存带逗号的小数(避免转为整数)
问题解决方案
问题根源分析
- 字符串转数值的错误处理:当前代码用隐式转换
Dim amount As Double = txtAmount.Text处理输入,对于以逗号作为小数分隔符的内容(如2,32),若系统默认文化不支持该格式,转换时会直接忽略逗号,导致数值变为232。同时用Double存储金额存在精度丢失风险,金额类型应优先使用Decimal。 - SQL拼接的格式与安全问题:直接拼接数值到SQL语句中,不仅容易因格式处理不当引发数据错误,还存在SQL注入风险。
具体修复步骤
1. 修正金额字符串转Decimal的逻辑
使用显式带文化的解析方法,确保正确识别逗号作为小数分隔符,同时改用Decimal类型存储金额:
Protected Sub btn_Submit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_Submit.Click If Not Page.IsValid Then Exit Sub End If Dim objNewAmount As New Amount If Not objCurrAmount Is Nothing Then objNewAmount.AmountID = objCurrAmount.AmountID isUpdate = True End If objNewAmount.AmountName = txtAmountName.Text ' 替换原转换逻辑 Dim amount As Decimal ' 根据用户所在地区指定文化,例如德语区用"de-DE",法语区用"fr-FR" Dim culture As CultureInfo = CultureInfo.GetCultureInfo("de-DE") If Not Decimal.TryParse(txtAmount.Text, NumberStyles.Number Or NumberStyles.AllowDecimalPoint, culture, amount) Then lblInfo.Text = "请输入正确的金额格式(如2,32)" Return End If objNewAmount.Amount = amount Dim IsError As Boolean = False Try objNewAmount.UpdateAmount() ' 原代码中objNewAmount.AmountName.UpdateAmount()疑似笔误,应调用类自身方法 Catch ex As Exception lblInfo.Text = ex.Message IsError = True End Try If Not IsError Then Response.Redirect("AmountList.aspx", True) End If End Sub
提示:若用户群体多样,可改用
CultureInfo.CurrentUICulture自动识别当前请求的文化。
2. 替换SQL拼接为参数化查询
彻底避免手动拼接SQL的格式问题与注入风险,修改UpdateAmount方法:
Public Sub UpdateAmount() Using conn As New SqlConnection("你的数据库连接字符串") conn.Open() Dim cmdText As String = " BEGIN " & GetNewShortIDQuery("m_Amount", "AmountID", "JH", "@NewID", 6, 4) & " INSERT INTO m_Amount SELECT @NewID, @AmountName, @Amount, @CreatorID, @CreatorIP, @CreatorDateTime, null, null, null; END" Using cmd As New SqlCommand(cmdText, conn) ' 添加参数 cmd.Parameters.Add("@NewID", SqlDbType.VarChar, 10).Direction = ParameterDirection.Output ' 匹配GetNewShortIDQuery的输出参数 cmd.Parameters.AddWithValue("@AmountName", Me.AmountName) cmd.Parameters.AddWithValue("@Amount", Me.Amount) cmd.Parameters.AddWithValue("@CreatorID", Me.CreatorID) cmd.Parameters.AddWithValue("@CreatorIP", Me.CreatorIP) cmd.Parameters.AddWithValue("@CreatorDateTime", Me.CreatorDateTime) cmd.ExecuteNonQuery() End Using End Using End Sub
参数化查询会自动处理Decimal类型与数据库decimal字段的格式映射,无需手动处理字符串转换。
3. 确保类属性类型一致性
确认Amount类中的Amount属性为Decimal类型(与数据库字段匹配),避免类型转换隐患:
Private _Amount As Decimal = 0 Public Property Amount() As Decimal Get Return _Amount End Get Set(ByVal value As Decimal) _Amount = value End Set End Property
内容的提问来源于stack exchange,提问作者Lydia
相关产品推荐
相关产品推荐

