-3

MS SQL のデータ テーブルにいくつかの値を保存しようとしていますが、データ型に問題があります。パラメータを使用して、これらの値を適切なデータ型に変換する必要があります

これは私のテーブルです、、、

テーブル画像

これは、データベースに値を渡すために使用しているコードです。パラメータを使用してデータを変換する必要があります。それを行うのを手伝ってください...

private void InsertRec(StringCollection sc)
    {
        var conn = new SqlConnection(GetConnectionString());
        var sb = new StringBuilder(string.Empty);
        var splitItems = (string[])null;
        foreach (string item in sc)
        {
            const string sqlStatement =
                "INSERT INTO DEL_PurchasesLines1 (DealerCode,InvoiceNo,InvoiceDate,ItemIdentityCode,PurchasingPrice,DiscountRate,Discount,IssueMode,Qty,Total,ExpireDate,BatchNumber,UploadedStatus,InsertedDate,UploadedDate,Force,Principle,NewTotal) VALUES";

            if (item.Contains(","))
            {
                splitItems = item.Split(",".ToCharArray());
                sb.AppendFormat("{0}('{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}','{16}','{17}','{18}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2], splitItems[3], splitItems[4], splitItems[5], splitItems[6], splitItems[7], splitItems[8], splitItems[9], splitItems[10], splitItems[11], splitItems[12], splitItems[13], splitItems[14], splitItems[15], splitItems[16], splitItems[17]);
            }
        }

        try
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(sb.ToString(), conn) { CommandType = CommandType.Text };
            cmd.ExecuteNonQuery();

            Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Script", "alert('Records Successfuly Saved!');", true);

        }
        catch (System.Data.SqlClient.SqlException ex)
        {
            string msg = "Insert Error:";
            msg += ex.Message;
            throw new Exception(msg);
        }
        finally
        {
            conn.Close();
        }
    }

これは、クエリに値を取り込む方法です。

    protected void btnSaave_Click(object sender, EventArgs e)
    {
        int rowIndex = 0;
        StringCollection sc = new StringCollection();
        if (ViewState["CurrentData"] != null)
        {
            DataTable dtCurrentTable = (DataTable)ViewState["CurrentData"];
            DataRow drCurrentRow = null;
            if (dtCurrentTable.Rows.Count > 0)
            {
                for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
                {
                    var dtDealerCode = txtIDealerCode.Text;
                    var dtInvoiceNo = txtInvoiceNumber.Text;
                    var dtInvoiceDate = txtInvoiceDate.Text;
                    var dtItemIdentityCode = (Label)GridView1.Rows[rowIndex].Cells[1].FindControl("ItemCode");
                    var dtPurchasingPrice = (Label)GridView1.Rows[rowIndex].Cells[3].FindControl("UnitPrice");
                    var dtDiscountRate = txtDiscount.Text;
                    var dtDiscount = txtProductDiscount.Text;
                    var dtIssueMode = ddlIssueMode.SelectedValue;
                    var dtQty = (Label)GridView1.Rows[rowIndex].Cells[6].FindControl("Quantity");
                    var dtTotal = (Label)GridView1.FooterRow.FindControl("GetTotal");
                    var dtExpireDate = (Label)GridView1.Rows[rowIndex].Cells[5].FindControl("ExpiaryDate");
                    var dtBatchNumber = (Label)GridView1.Rows[rowIndex].Cells[4].FindControl("Batch");
                    var dtUploadedStatus = txtInvoiceDate.Text;
                    var dtInsertedDate = "1";
                    var dtUploadedDate = txtInvoiceDate.Text;
                    var dtForce = txtForce.Text;
                    var dtPrinciple = txtPrinciple.Text;
                    var NewTotal = (Label)GridView1.FooterRow.FindControl("GetQuantity");

                    sc.Add(dtDealerCode + "," + dtInvoiceNo + "," + dtInvoiceDate + "," + dtItemIdentityCode.Text + "," + dtPurchasingPrice.Text + "," + dtDiscountRate + "," + dtDiscount + "," + dtIssueMode + "," + dtQty.Text + "," + dtTotal.Text + "," + dtExpireDate + "," + dtBatchNumber.Text + "," + dtUploadedStatus + "," + dtInsertedDate + "," + dtUploadedDate + "," + dtForce + "," + dtPrinciple + "," + dtPrinciple + "," + NewTotal.Text);
                    rowIndex++;
                }

                InsertRec(sc);
            }
        }
    }
4

2 に答える 2

0

正しい方法は、各項目のパラメーターを持つか、クラス型を介して、つまり次のいずれかを使用して、期待する特定の値を要求するメソッドを構築することです。

private void InsertRec(DEL_PurchasesLines1 lineToInsert)

whereDEL_PurchasesLines1は作成するクラス (テーブルにちなんで名付けられたもの)、または次のとおりです。

private void InsertRec(string DealerCode,string InvoiceNo,DateTime InvoiceDate,
            string ItemIdentityCode,decimal PurchasingPrice, decimal DiscountRate,
            decimal Discount,string IssueMode,decimal Qty,decimal Total,
            DateTime ExpireDate,string BatchNumber,string UploadedStatus,
            string InsertedDate,DateTime UploadedDate,string Force,
            decimal Principle,decimal NewTotal)

FWIW、1 つのテーブルに多くの列があるということは、ほとんどの場合、テーブルの設計に問題があることを意味しますが、ここではそのままにしておきます。2 番目の方法を使用すると、ボタンのクリックは次のようになります。

protected void btnSave_Click(object sender, EventArgs e)
{
    if (ViewState["CurrentData"] == null) return;
    DataTable dtCurrentTable = (DataTable)ViewState["CurrentData"];
    if (dtCurrentTable.Rows.Count == 0) return;

    int rowIndex = 0;

    var dtDealerCode = txtIDealerCode.Text;
    var dtInvoiceNo = txtInvoiceNumber.Text;
    var dtInvoiceDate = DateTime.Parse(txtInvoiceDate.Text);
    var dtDiscountRate = decimal.Parse(txtDiscount.Text);
    var dtDiscount = decimal.Parse(txtProductDiscount.Text);
    var dtIssueMode = ddlIssueMode.SelectedValue;
    var dtUploadedStatus = DateTime.Parse(txtInvoiceDate.Text);
    var dtInsertedDate = "1"; //Really? 
    var dtUploadedDate = DateTime.Parse(txtInvoiceDate.Text);
    var dtForce = txtForce.Text;
    var dtPrinciple = decimal.Parse(txtPrinciple.Text);

    for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
    {
        var dtItemIdentityCode = (Label)GridView1.Rows[rowIndex].Cells[1].FindControl("ItemCode");
        var dtPurchasingPrice = decimal.Parse((Label)GridView1.Rows[rowIndex].Cells[3].FindControl("UnitPrice"));
        var dtQty = decimal.Parse((Label)GridView1.Rows[rowIndex].Cells[6].FindControl("Quantity"));
        var dtTotal = decimal.Parse((Label)GridView1.FooterRow.FindControl("GetTotal"));
        var dtExpireDate = DateTime.Parse((Label)GridView1.Rows[rowIndex].Cells[5].FindControl("ExpiaryDate"));
        var dtBatchNumber = (Label)GridView1.Rows[rowIndex].Cells[4].FindControl("Batch");
        var NewTotal = decimal.Parse((Label)GridView1.FooterRow.FindControl("GetQuantity"));

        InsertRec(dtDealerCode,dtInvoiceNo,dtInvoiceDate,dtItemIdentityCode,
            dtPurchasingPrice,dtDiscountRate,dtDiscount,dtIssueMode,dtQty,
            dtTotal,dtExpireDate,dtBatchNumber,dtUploadedStatus,dtInsertedDate,
            dtUploadedDate,dtForce,dtPrinciple,NewTotal);

        rowIndex++;
    }
}

すべてをまとめると、次のInsertRec()ようになります。

private void InsertRec(string DealerCode,string InvoiceNo,DateTime InvoiceDate,
            string ItemIdentityCode,decimal PurchasingPrice, decimal DiscountRate,
            decimal Discount,string IssueMode,decimal Qty,decimal Total,
            DateTime ExpireDate,string BatchNumber,string UploadedStatus,
            string InsertedDate,DateTime UploadedDate,string Force,
            decimal Principle,decimal NewTotal)
{

    const string sqlStatement =
            "INSERT INTO DEL_PurchasesLines1 (" +
              "DealerCode,InvoiceNo,InvoiceDate,ItemIdentityCode,PurchasingPrice,DiscountRate,Discount,IssueMode,Qty,Total,ExpireDate,BatchNumber,UploadedStatus,InsertedDate,UploadedDate,Force,Principle,NewTotal" + 
            ") VALUES (" +
              "@DealerCode, @InvoiceNo, @InvoiceDate, @ItemIdentityCode, @PurchasingPrice, @DiscountRate, @Discount, @IssueMode, @Qty, @Total, @ExpireDate, @BatchNumber, @UploadSTatus, @InsertedDate, @UploadedDate, @Force, @Principle, @NewTotal" +
            ")";

    using (conn = new SqlConnection(GetConnectionString())
    using (cmd = new SqlCommand(sqlStatement, conn))
    {
        cmd.Parameters.Add("@DealerCode", SqlDbType.NVarChar, 10).Value = DealerCode;
        cmd.Parameters.Add("@InvoiceNo", SqlDbType.NVarChar, 10).Value = InvoiceNo;
        cmd.Parameters.Add("@InvoiceDate", SqlDbType.DateTime).Value = InvoiceDate;
        cmd.Parameters.Add("@ItemIdentityCode", SqlDbType.NVarChar, 10).Value = ItemIdentityCode;
        cmd.Parameters.Add("@PurchasingPrice", SqlDbType.Decimal).Value = PurchasingPrice;
        cmd.Parameters.Add("@DiscountRate", SqlDbType.Decimal).Value = DiscountRate;
        //...

        conn.Open();
        cmd.ExecuteNonQuery();
    }

    Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Script", "alert('Records Successfuly Saved!');", true);
}

Sql インジェクションと呼ばれるちょっとしたことのおかげで、StringBuilder と Format 文字列で行っていたことはまったく不適切でした。かなり重要なので、必ず読んでおくべきです。

また、挿入を単一のバッチにグループ化しようとしていることがわかります。それは素晴らしいことですが、接続プーリングのおかげで、実際にはあまり役に立ちません。また、正しいクエリのパラメーター化を行うのも難しくなります。ただし、不可能ではないので、other メソッド シグネチャを使用した例を示します。これにより、少し簡単になります。

private void InsertRec(DEL_PurchasesLines1[] linesToInsert)
{
    const string sqlBase =
            "INSERT INTO DEL_PurchasesLines1 (" +
              "(DealerCode,InvoiceNo,InvoiceDate,ItemIdentityCode,PurchasingPrice,DiscountRate,Discount,IssueMode,Qty,Total,ExpireDate,BatchNumber,UploadedStatus,InsertedDate,UploadedDate,Force,Principle,NewTotal)" + 
            " VALUES ";

    const string valueBase = 
              "{0}(@DealerCode{1}, @InvoiceNo{1}, @InvoiceDate{1}, @ItemIdentityCode{1}, @PurchasingPrice{1}, @DiscountRate{1}, @Discount{1}, @IssueMode{1}, @Qty{1}, @Total{1}, @ExpireDate{1}, @BatchNumber{1}, @UploadSTatus{1}, @InsertedDate{1}, @UploadedDate{1}, @Force{1}, @Principle{1}, @NewTotal{1})";

    var sb = new StringBuilder(sqlBase);
    if (DEL_PurchasesLines1.Length > 1) sb.Append("(")
    var delimiter = "";
    for (int i = 0;i<DEL_PurchasesLines1.Length;i++)
    {
         sb.AppendFormat(valueBase, i, delimiter);
         delimiter = ",";
    }
    if (DEL_PurchasesLines1.Length > 1) sb.Append(")")

    using (conn = new SqlConnection(GetConnectionString())
    using (cmd = new SqlCommand(sqlStatement, conn))
    {

        for (int i = 0;i<DEL_PurchasesLines1.Length;i++)
        {
            cmd.Parameters.Add("@DealerCode" + i, SqlDbType.NVarChar, 10).Value = linesToInsert[i].DealerCode;
            cmd.Parameters.Add("@InvoiceNo" + i, SqlDbType.NVarChar, 10).Value = linesToInsert[i].InvoiceNo;
            cmd.Parameters.Add("@InvoiceDate + i", SqlDbType.DateTime).Value = linesToInsert[i].InvoiceDate;
            cmd.Parameters.Add("@ItemIdentityCode" + i, SqlDbType.NVarChar, 10).Value = linesToInsert[i].ItemIdentityCode;
            cmd.Parameters.Add("@PurchasingPrice" + i, SqlDbType.Decimal).Value = linesToInsert[i].PurchasingPrice;
            cmd.Parameters.Add("@DiscountRate" + i, SqlDbType.Decimal).Value = linesToInsert[i].DiscountRate;
        //...
        }
        conn.Open();
        cmd.ExecuteNonQuery();
    }
}
于 2013-09-22T05:20:31.160 に答える
0

これは一種の厄介なコードです。あなたがプログラミングに慣れていないかどうかはわかりませんが、これにはストアドプロシージャを使用する必要があります。プロシージャは、引数として渡す必要がある14個程度のパラメータを定義します。これにより、パラメーター化されたストアド プロシージャ呼び出しのパラメーターを追加するようにコードがガイドされます。各引数は厳密に型指定される必要があり、テーブルの各列値に対して適切な変換を行うようにガイドされます。また、すべてのテーブル列の値をパブリック プロパティとして定義する C# クラスを作成する必要があります。VB.NET で申し訳ありませんが、この単純なデータ アクセス レイヤー (DAL) のサンプル スニペットでアイデアを得ることができます。UpdateOffer の名前を AddUpdateOffer に変更できます。これにより、レコード ID を AddUpdate に渡すことで、レコードが存在するかどうかを確認できます。更新の場合はストアド プロシージャ、

 Public Class Offer

        Public OfferID As Integer
        Public PropertyID As Integer
        Public AgentUserID As Integer
        Public AgentName As String
        Public BuyerUserID As Integer
        Public BuyerName As String
        Public BuyerType As String
        Public Offer As Integer
        Public NetOffer As Integer
        Public ClosingCost As Integer
        Public Allowances As Integer
        Public RepairCosts As Integer
        Public TotalCredits As Integer
        Public OfferType As String
        Public OfferDate As String
        Public ProxyOffer As Integer
        Public NetProxyOffer As Integer
        Public ResultResponse As SUBMIT_OFFER_RESULT
        'Public ResultAcceptedOffer As Integer
        Public ResultAcceptedNetOffer As Integer
        'Public ResultHighestOffer As Integer
        Public ResultHighestNetOffer As Integer
        Public Notifications As ArrayList = New ArrayList
        Public EarnestMoneyDeposit As Integer
        Public DownPayment As Integer
        Public TypeOfFinancing As String
        Public OfferStatus As String
        Public Note As String
        Public Visble As Boolean = True
        Public OfferStatusChangedDate As DateTime
        Public EstimatedCloseDate As DateTime
        Public SourceType As String

        Public Sub GetOffer(ByVal offerID As Integer)

            Dim offerDB As OSP.DataAccess.OfferDB = New OSP.DataAccess.OfferDB
            Dim rs As SqlClient.SqlDataReader
            rs = offerDB.GetOffer(offerID)
            Do While rs.Read
                Me.OfferID = offerID
                Me.PropertyID = rs("PROPERTY_ID")
                Me.AgentUserID = rs("AGENT_USER_ID")
                Me.BuyerUserID = IIf(IsDBNull(rs("BUYER_USER_ID")), 0, rs("BUYER_USER_ID"))
                Me.Offer = rs("OFFER")
                Me.NetOffer = rs("NET_OFFER")
                Me.TotalCredits = rs("TOTAL_CREDITS")
                Me.ProxyOffer = rs("PROXY_OFFER")
                Me.OfferType = rs("OFFERTYPE")
                Me.OfferDate = rs("OFFER_DATE")
                Me.DownPayment = IIf(IsDBNull(rs("DOWN_PAYMENT")), 0, rs("DOWN_PAYMENT"))
                Me.EarnestMoneyDeposit = IIf(IsDBNull(rs("EARNEST_MONEY_DEPOSIT")), 0, rs("EARNEST_MONEY_DEPOSIT"))
                Me.TypeOfFinancing = rs("TYPE_OF_FINANCING")
                Me.BuyerName = GlobalFunctions.DefaultString(rs("BUYER_NAME"))
                Me.BuyerType = GlobalFunctions.DefaultString(rs("BUYER_TYPE"))
                Me.AgentName = rs("OFFER_BY_NAME")
                Me.OfferStatus = GlobalFunctions.DefaultString(rs("OFFER_STATUS"))
                Me.Note = GlobalFunctions.DefaultString(rs("NOTE"))
                Me.OfferStatusChangedDate = IIf(IsDBNull(rs("OFFER_STATUS_CHANGED_DATE")), Me.OfferStatusChangedDate, rs("OFFER_STATUS_CHANGED_DATE"))
                Me.Visble = IIf(IsDBNull(rs("VISIBLE")), True, rs("VISIBLE"))
                Me.EstimatedCloseDate = IIf(IsDBNull(rs("ESTIMATED_CLOSE_DATE")), DateTime.MinValue, rs("ESTIMATED_CLOSE_DATE"))
            Loop

            Try
                If Not rs.IsClosed Then
                    rs.Close() : rs = Nothing
                End If
                If Not offerDB Is Nothing Then
                    offerDB.Dispose() : offerDB = Nothing
                End If
            Catch : End Try

        End Sub

        Public Function UpdateOffer() As Integer

            Dim offerDB As OSP.DataAccess.OfferDB = New OSP.DataAccess.OfferDB
            Return offerDB.UpdateOffer(Me)

        End Function
End Class

 Public Class OfferDB
        Implements System.IDisposable


        Dim db As SQLDatabase

        Public Sub New()
            db = New SQLDatabase(GlobalSettings.GetDefaultConnectionString)
        End Sub

        Public Sub Dispose() Implements System.IDisposable.Dispose

            If Not db Is Nothing Then
                db = Nothing
            End If

        End Sub

  Public Function GetOffer(ByVal offerID As Integer) As SqlClient.SqlDataReader

            Dim dbCommand As DbCommand = db.GetStoredProcCommand("OSP_GET_OFFER")
            db.AddInParameter(dbCommand, "@OFFER_ID", SqlDbType.Int, offerID)

            Try
                Return db.ExecuteReader(dbCommand)
            Catch ex As Exception
                Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "EXCEPTION_CRITICAL")
                If (rethrow) Then
                    Throw
                End If
            End Try


        End Function


        Public Function UpdateOffer(ByVal offer As OSP.Offer) As Integer

            Dim dbCommand As DbCommand = db.GetStoredProcCommand("OSP_UPDATE_OFFER")

            db.AddInParameter(dbCommand, "@OFFER_ID", SqlDbType.Int, offer.OfferID)
            db.AddInParameter(dbCommand, "@BUYER_USER_ID", SqlDbType.Int, offer.BuyerUserID)
            db.AddInParameter(dbCommand, "@OFFER", SqlDbType.Int, offer.Offer)
            db.AddInParameter(dbCommand, "@TOTAL_CREDITS", SqlDbType.Int, offer.TotalCredits)
            db.AddInParameter(dbCommand, "@OFFER_TYPE", SqlDbType.VarChar, offer.OfferType)
            db.AddInParameter(dbCommand, "@OFFER_DATE", SqlDbType.VarChar, offer.OfferDate)
            db.AddInParameter(dbCommand, "@TYPE_OF_FINANCING", SqlDbType.VarChar, offer.TypeOfFinancing)
            db.AddInParameter(dbCommand, "@DOWN_PAYMENT", SqlDbType.Int, offer.DownPayment)
            db.AddInParameter(dbCommand, "@EARNEST_MONEY_DEPOSIT", SqlDbType.Int, offer.EarnestMoneyDeposit)
            db.AddInParameter(dbCommand, "@OFFER_STATUS", SqlDbType.VarChar, offer.OfferStatus)
            db.AddInParameter(dbCommand, "@NOTE", SqlDbType.VarChar, offer.Note)
            If Not offer.OfferStatusChangedDate = DateTime.MinValue Then
                db.AddInParameter(dbCommand, "@OFFER_STATUS_CHANGED_DATE", SqlDbType.DateTime, offer.OfferStatusChangedDate)
            End If

            Try
                Return db.ExecuteScalar(dbCommand)
            Catch ex As Exception
                Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "EXCEPTION_CRITICAL")
                If (rethrow) Then
                    Throw
                End If
            End Try

        End Function
End Class
于 2013-09-22T05:03:21.053 に答える