【问题标题】:Problems with Passing Decimal Values From C# to SQL Database将十进制值从 C# 传递到 SQL 数据库的问题
【发布时间】:2016-11-01 03:51:26
【问题描述】:

我正在尝试将十进制值从 C# 传递到 SQL 数据库。我构建了一个 INSERT 查询字符串并使用 SqlCommand 将其发送。我遇到的问题是,当我在 Windows 窗体中输入值时,它们以逗号分隔小数点(即 55,679)保存。这在 SQL 查询字符串中很明显(我已经通过调试进行了检查)。但似乎数据库查询需要一个小数点(即 55.679)。这可能与我所在的地区和那里的标准有关(即欧洲使用“,”作为小数点分隔符)。有人知道怎么设置吗?

函数的代码如下。问题存在于Vmax、Vmin、Imax。

public bool addBattery(Battery b)
    {
        bool outcome = false;

        string sql = @"INSERT INTO [BATTERY_INFO]
            (BatteryType, VoltageMax, VoltageMin, Capacity, CurrentMax, Manufacturer, Serial)
            VALUES ('" + b.BatteryType.ToString() + "'," + b.Vmax + "," + b.Vmin + "," 
            + b.Capacity + ","+b.Imax+ ",'"+b.Manufacturer.ToString()+"','"+b.Serial.ToString()+"')";

        SqlCommand command = new SqlCommand(sql, this.sql_conn);

        try
        {
            command.ExecuteNonQuery();
            MessageBox.Show("Inserted Battery Successfully");
            outcome = true;
        }
        catch (Exception e)
        {
            MessageBox.Show("SQL INSERT error \n\n" + e.Message);
        }


        return outcome;
    }

【问题讨论】:

  • 请使用参数化查询而不是字符串连接:msdn.microsoft.com/en-us/library/…
  • 正如@Stanley 建议的那样,参数化查询将解决小数分隔符的问题并有助于提高数据库性能。
  • 你能告诉我们电池类的样子吗?而且,还有更好的插入方法。试试这样的方法:new SqlParameter("@VmaxParameter", SqlDbType.Decimal, b.VMax),
  • 我会这样做的,谢谢。只是出于兴趣,参数化查询是否也为软件增加了安全性?我在this thread 中看到他们这样做了。有人可以发送一个链接来确认吗?
  • @tdwolff:是的,这也增加了安全性,想象一下如果您在b.Imax 值中获得值666,'uh','oh'); DROP TABLE BATTERY_INFO; -- 会发生什么。

标签: c# sql-server decimal


【解决方案1】:

正如 cmets 中所指出的,使用参数化查询将解决小数问题并防止可能的安全风险,例如 sql 注入。该方法看起来像这样。

我假设您 Open() 和 Close() 在其他地方连接,因为我在您的代码中看不到它。

        {
        bool outcome = false;
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = this.sql_conn;

        cmd.Parameters.AddWithValue("BatteryType", b.BatteryType);
        cmd.Parameters.AddWithValue("VoltageMax", b.Vmax);
        cmd.Parameters.AddWithValue("Capacity", b.Capacity);
        cmd.Parameters.AddWithValue("CurrentMax", b.Imax);
        cmd.Parameters.AddWithValue("Manufacturer", b.Manufacturer.ToString());
        cmd.Parameters.AddWithValue("Serial", b.Serial.ToString());

        try
        {
            cmd.ExecuteNonQuery();
            MessageBox.Show("Inserted Battery Successfully");
            outcome = true;
        }
        catch(Exception e)
        {
            MessageBox.Show("SQL INSERT error \n\n" + e.Message);
        }

        return outcome;
    }

【讨论】:

  • 感谢您的回答。连接在程序启动时打开,并在应用程序运行时保持打开状态。这是好习惯吗?当应用程序关闭时它会关​​闭。该应用程序用于监视来自某些硬件的实时数据(从另一个位置发布到数据库)。这就是为什么我只是保持连接打开。
  • @tdwolff - 并非如此,理想情况下您将连接包装在 using() 语句中。你开得很晚,然后尽快关门。有人可能会争辩说,只要您知道自己在做什么,就可以保持开放,但这是一种冒险的方法。你会知道多久?全局变量(例如您的连接)的可维护性如何?它必须是全球性的吗?不,它没有。尽可能保持变量本地化。这是一个SO question and answers,它讨论了连接处理。
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 2014-05-10
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多