【问题标题】:Insert numerical (decimal) data from textbox values从文本框值插入数字(十进制)数据
【发布时间】:2012-12-05 21:21:30
【问题描述】:

我对以下问题感到困惑;

我有一个 C# (WindowsForms) 应用程序,我连接到 SQL Server 数据库,并且在我开始使用数字数据之前,插入、选择、更新都没有问题;

此应用程序的目的是管理员工、他们的合同、工作费率、合同期限、小时费率......并用它来做一些有趣的计算,没什么魔法。

基本上,我需要在我的数据库中存储一些格式为“0000,0000”的值(十进制?双精度?浮点数?)。

  • 在我的数据库中,我已将表中的所有列设置为我需要将这些“000,0000”值设为十进制

  • 在我的表单中,我没有为我的文本框指定任何特定属性,

  • 为了插入,我使用了我定义了十进制参数的方法

        public void createNewContract(int employeeId, string agency, string role, string contractType, string startDate,
        string endDate, string lineManager, string reportTo, string costCenter, string functionEng, string atrNo, string atrDate, string prNo, string prDate,
        string poNo, string poDate, string comments, decimal duration, decimal workRatePercent, string currency, decimal hourlyRate, decimal value)
    {
        if (conn.State.ToString() == "Closed")
        {
            conn.Open();
        }
        SqlCommand newCmd = conn.CreateCommand();
        newCmd.Connection = conn;
        newCmd.CommandType = CommandType.Text;
        newCmd.CommandText = "INSERT INTO tblContracts (CreatedById, CreationDate, EmployeeId, Role, ContractType, StartDate, "
        + "EndDate, Agency, LineManager, ReportTo, CostCenter, FunctionEng, AtrNo, AtrDate, PrNo, PrDate, PoNo, PoDate, Comments, Duration, WorkRatePercent, Currency, HourlyRate, Value)"
        + "VALUES ('" + connectedUser.getUserId() + "','" + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss") + "','" + employeeId + "','" + role + "','" + contractType
        + "','" + startDate + "','" + endDate + "','" + agency + "','" + lineManager + "','" + reportTo + "','" + costCenter + "','" + functionEng + "','" + atrNo + "','" + atrDate + "','" + prNo
         + "','" + prDate + "','" + poNo + "','" + poDate + "','" + comments + "','" + duration + "','" + workRatePercent + "','" + currency + "','" + hourlyRate + "','" + value + "')";
        newCmd.ExecuteNonQuery();
        MessageBox.Show("Contract has been successfully created", "Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    

(通过这种方法,我只需要插入一个持续时间(nb小时),工作率百分比,每小时费率(货币货币)和价值(货币货币)为00,0000)

  • 为了捕获我的文本框值并通过我的方法“createNewContrat”发送它们,我尝试过 Convert.ToDecimal(this.txtDuration.Text) 和许多其他对我来说似乎不错的东西,但我无法理解机制,而且我当然没有使用最实用/最聪明的解决方案......

我不断收到以下错误;

System.FormatException: Le format de la chaîne d'entrée est 不正确。 = 输入/输入字符串的格式不正确
à System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
à System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
à System.Convert.ToDecimal(String value)

你会推荐什么?

【问题讨论】:

  • 你的 SQL 语句如果被参数化会更安全,更易读
  • SQL 注入:Exploits Of A Mom
  • 我建议您创建一个 Contract 类作为所有字段的容器,而不是使用 20 多个参数的方法。
  • 干杯菲尔伯特,图片示例很清楚:DD
  • 不客气。另外,由于您是 StackOverflow 的新手,我想通知您,您可以通过勾选答案旁边的勾号来为好的答案投票并接受对您帮助最大的答案。在本网站上,点赞或接受的答案都算作“感谢”。

标签: c# sql insert numeric


【解决方案1】:

首先,在处理SqlConnection 和SqlCommand 以及所有其他实现IDisposable 的类时,请始终使用using,请阅读更多信息。

第二件事,始终使用带有SqlCommand 的参数,并且永远不要将值作为字符串传递给sql 字符串。这是一个严重的安全问题。除了这些参数之外,还可以让您的代码人性化!

// Always use (using) when dealing with Sql Connections and Commands
using (sqlConnection conn = new SqlConnection())
{
    conn.Open();

    using (SqlCommand newCmd = new SqlCommand(conn))
    {
        newCmd.CommandType = CommandType.Text;

        newCmd.CommandText = 
              @"INSERT INTO tblContracts (CreatedById, CreationDate, EmployeeId, Role, ContractType, StartDate, EndDate, Agency, LineManager, ReportTo, CostCenter, FunctionEng, AtrNo, AtrDate, PrNo, PrDate, PoNo, PoDate, Comments, Duration, WorkRatePercent, Currency, HourlyRate, Value) 
              VALUES (@UserID, @CreationDate, @EmployeeID, @Role.....etc)";

        // for security reasons (Sql Injection attacks) always use parameters
        newCmd.Parameters.Add("@UserID", SqlDbType.NVarChar, 50)
             .Value = connectedUser.getUserId();

        newCmd.Parameters.Add("@CreationDate", SqlDbType.DateTime)
             .Value = DateTime.Now;

        // To add a decimal value from TextBox
        newCmd.Parameters.Add("@SomeValue", SqlDbType.Decimal)
             .Value = System.Convert.ToDecimal(txtValueTextBox.Text);

        // complete the rest of the parameters
        // ........

        newCmd.ExecuteNonQuery();

        MessageBox.Show("Contract has been successfully created", "Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

【讨论】:

    【解决方案2】:

    这不是您问题的直接答案,但请(!)用这个替换这个丑陋的方法:

    为您的合同创建一个类。这将使处理合同变得更加容易。如果您有多种方法以某种方式处理合约,那么当向合约添加属性时,您将不必更改几乎无穷无尽的所有参数列表。

    public class Contract
    {
        public int EmployeeID { get; set; }
        public string Agency { get; set; }
        public string Role { get; set; }
        ... and so on
    }
    

    并将方法签名更改为

    public void CreateNewContract(Contract contract)
    

    从数据库加载合同的方法的标题如下所示

    public List<Contract> LoadAllContracts()
    
    // Assuming contractID is the primary key
    public Contract LoadContractByID(int contractID)
    

    比返回 1000 个变量要容易得多!

    您可以创建一个新合同

    var contract = new Contract {
        EmployeeID = 22,
        Agency = "unknown",
        Role = "important", 
        ...
    };
    

    另外(正如其他人已经指出的那样)使用命令参数。

    newCmd.Parameters.AddWithValue("@EmployeeID", contract.EmployeeID);
    newCmd.Parameters.AddWithValue("@Agency", contract.Agency);
    newCmd.Parameters.AddWithValue("@Role", contract.Role);
    

    (HaLaBi 的帖子展示了如何制定插入命令字符串。)

    【讨论】:

    • 谢谢奥利维尔!我会继续这样谢谢大家的宝贵帮助和建议!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    相关资源
    最近更新 更多