【问题标题】:SQL C# Doubles with decimalsSQL C# 带小数的双精度数
【发布时间】:2012-03-02 10:11:52
【问题描述】:

我正在尝试在已转换的 SQL 更新语句中输入双精度值(参见代码 1),以将他的数字保留在逗号后面。

(1)

double.TryParse(splitline[8], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out natMB //conversion

(2) 将我的值放入我的 SQL 语句的过程中,我将 natMB 放入“Verbruikgegevens”,索引位置 2。0 或 1 表示我输入的数据是否正在漫游。这是声明它是漫游数据还是国家数据的 if 语句的一部分。

sqlStatementUpdate(TrafficdataID, 0,     
(Convert.ToDouble(Verbruikgegevens.Rows[intCount].ItemArray[2],   
CultureInfo.InvariantCulture))

(3)Visual Studio(C#)中的SQL语句

public void sqlStatementUpdate(long TrafficdataID, byte Roaming, double Value)
{
    SqlCommand sqlCmd = new SqlCommand();
    sqlCmd.Connection = connection2;
    sqlCmd.CommandType = CommandType.StoredProcedure;
    sqlCmd.CommandText = "SP_SCTrafficdataDetailUpdate";
    DataAccessHelper.AddParam(sqlCmd, "TDDValue", SqlDbType.Decimal, Convert.ToDecimal(Value));
    DataAccessHelper.AddParam(sqlCmd, "TrafficdataID", SqlDbType.BigInt, TrafficdataID);
    DataAccessHelper.AddParam(sqlCmd, "TDDRoaming", SqlDbType.Bit, Roaming);
    DataAccessHelper.ExecSProcDS(sqlCmd);
}

(4) 数据访问助手

internal static class DataAccessHelper
{
    public static void AddParam(SqlCommand cmd, string columnName, SqlDbType dbType, object paramvalue)
    {
        if (paramvalue is DateTime)
        {
            if (((DateTime)paramvalue).Date == DateTime.MinValue.Date)
            {
                paramvalue = DBNull.Value;
            }

        }

        if (paramvalue == null)
        {
            paramvalue = DBNull.Value;
        }

        string param = "@" + columnName;
        if (!cmd.Parameters.Contains(param))
        {
            if (dbType == SqlDbType.VarChar || dbType == SqlDbType.NVarChar || dbType == SqlDbType.Char || dbType == SqlDbType.NChar)
                cmd.Parameters.Add(param, dbType, 4000);
            else
                cmd.Parameters.Add(param, dbType);

            cmd.Parameters[param].SourceColumn = columnName;
            cmd.Parameters[param].Value = paramvalue;
        }
    }

    public static DataSet ExecSProcDS(SqlCommand cmd)
    {
        DataSet ds = new DataSet();

        try
        {
            SqlDataAdapter da = new SqlDataAdapter();
            da.SelectCommand = cmd;
            da.Fill(ds);
        }
        catch (Exception ex)
        {
            throw (ex);
        }
        return ds;
    }

(5) SQL 语句

ALTER PROCEDURE [dbo].[SP_SCTrafficdataDetailUpdate] @TDDValue decimal, @TrafficdataID bigint, @TDDRoaming bit
AS
BEGIN
UPDATE    TR_SCTrafficDataDetail
SET              TDDValue = @TDDValue
WHERE     (TDDType = 'Data') AND (TrafficDataID = @TrafficdataID) AND (TDDRoaming = @TDDRoaming)
END

问题:在将数据导入到我的 sqltable 时,我是否可以继续使用双精度数,并将我的数字放在逗号后面?现在它似乎没有那么好用......我在我的 SQLTable 中将我的值定义为小数

【问题讨论】:

  • 您的问题似乎没有问题...无论如何,如果您使用数据库中的 Decimal 字段,我建议您在 C# 中使用 Decimal 变量来保持兼容和/或避免舍入错误。
  • 小数不会降低性能吗?
  • 您错过了一个问题。 sql 是否会删除您尝试插入的数字的小数部分?
  • 十进制可能比双精度稍慢,但这实际上取决于您的问题到底是什么。你愿意为了准确而放弃一些速度吗?
  • 仅处理 10000 条记录需要 15 分钟,这听起来像是您的整体设计有问题,我认为如果您修复了设计缺陷,您可以只使用小数,而一开始就没有问题。

标签: c# sql double decimal


【解决方案1】:

所以问题是:

  • 我有代表数字的文本输入,有时使用逗号,有时使用句点作为小数分隔符。如何可靠地将这些转换为数字?

答案:这与 SQL 数据类型无关。您需要首先编写可靠的 C# 代码来将数字转换为双精度或小数。两者都可以 - 您应该使用与您的数据库匹配的任何一个。

Invariant 文化需要将句点作为小数点,而不是逗号。因此,如果您使用逗号作为小数分隔符,则说明您使用了错误的文化。

如果您知道数字的格式,请使用重载的 Parse 并直接指定格式。

如果是来自用户输入,则使用用户的文化,或者训练用户使用什么格式。

最后,如果你有一些奇怪的格式,你可能需要编写自己的代码来使用正则表达式来规范格式。

速度问题

10000 行不算什么,它需要几秒钟而不是几分钟。

我注意到您正在为每一行创建一个新的 SqlCommand。每次您这样做时,它都必须转到 SQL 服务器并将元数据与您正在调用的存储过程相匹配。

只需创建一次,然后通过将值设置为新行中的值来重新使用它。只是不要忘记将 NULL 设置为 DBNull.Value。

【讨论】:

  • 对于速度问题。您的意思是定义一次,然后调用另一个过程来更改命令中的变量?
  • 我不认为它会那样工作,我不会得到一个添加参数的过度循环吗?
  • 您只需添加一次,在创建 SqlCommand 时将值设置为 DBNull.Value。那你说cmdObject.Parameters["@paramName"].Value = valueVariable;
猜你喜欢
  • 1970-01-01
  • 2011-07-22
  • 1970-01-01
  • 2015-03-20
  • 1970-01-01
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
相关资源
最近更新 更多