0

私は次の問題に混乱しています。

SQL Server DBに接続するC#(WindowsForms)アプリケーションがあり、数値データの操作を開始するまで、INSERT、SELECT、UPDATE...に問題はありません。

このアプリケーションの目的は、従業員、その契約、仕事の割合、契約期間、時給を管理することです...そしてそれを使って面白い計算を行うことです。魔法は何もありません。

基本的に、DBに「0000,0000」の形式でいくつかの値(decimal?double?float?)を格納する必要があります。

  • 私のDBでは、これらの「000,0000」値を10進数にする必要があるすべての列を含むテーブルを設定しました

  • 私のフォームでは、テキストボックスに特定のプロパティを指定していません。

  • 挿入するには、10進引数を定義したメソッドを使用します

        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:Leformatdelachaîned'entréeestが正しくありません。=入力/入力文字列の形式が正しくありませ
んà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(文字列値)

あなたは何をお勧めします?

4

2 に答える 2

1

まず第一に、をusing処理するときは常に使用しSqlConnectionSqlCommand実装する他のすべてのクラスは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);
    }
}
于 2012-12-05T21:34:28.313 に答える
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の投稿は、挿入コマンド文字列を作成する方法を示しています。)

于 2012-12-05T21:59:54.783 に答える