从文本框值中插入数字(十进制)数据

时间:2012-12-05 21:21:31

标签: c# sql insert numeric

我对以下问题感到困惑;

我有一个C#(WindowsForms)应用程序,我连接到SQL Server数据库,没有问题INSERT,SELECT,UPDATE ......直到我开始处理数值数据;

这个应用程序的目的是管理员工,他们的合同,工作率,合同期限,每小时费率...并做一些有趣的计算,没有魔法

基本上,我需要在我的数据库中存储一些格式为“0000,0000”的值(decimal?double?float?)。

  • 在我的数据库中,我已将表格设置为所有列,我需要这些“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);
    }
    

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

  • 要捕获我的文本框值并通过我的方法'createNewContrat'发送它,我试过了 Convert.ToDecimal(this.txtDuration.Text)和其他许多对我来说都很好的东西,但我无法理解机制,我当然也没有使用最实用/最聪明的解决方案......

我一直收到以下错误;

  

System.FormatException:Le format delachaîned'entréeest错误。 =输入/输入字符串的格式不正确
     àSystem.Number.StringToNumber(String str,NumberStyles options,NumberBuffer& number,NumberFormatInfo info,Boolean parseDecimal)
     àSystem.Number.ParseDecimal(字符串值,NumberStyles选项,NumberFormatInfo numfmt)
     àSystem.Convert.ToDecimal(字符串值)

你会推荐什么?

2 个答案:

答案 0 :(得分:1)

首先,在处理usingSqlConnection时始终使用SqlCommand,而实现IDisposable的所有其他类只需阅读更多相关信息。

第二件事,始终使用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);
    }
}

答案 1 :(得分:0)

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

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

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的帖子展示了如何制定插入命令字符串。)