C# 如何使用参数转换为正确的数据类型。使用SQL查询?

C# 如何使用参数转换为正确的数据类型。使用SQL查询?,c#,asp.net,sql,sql-server,C#,Asp.net,Sql,Sql Server,我试图将一些值保存到MS SQL中的数据表中,但数据类型有一些问题。我需要使用参数将这些值转换为正确的数据类型 这是我的桌子 这是我用来将值传递到数据库的代码,,我需要使用参数来转换数据,请帮助我这样做 private void InsertRec(StringCollection sc) { var conn = new SqlConnection(GetConnectionString()); var sb = new StringBuilder(st

我试图将一些值保存到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);
            }
        }
    }

这是一种令人讨厌的代码。我不知道您是否是编程新手,但您应该为此使用一个存储过程,该过程定义了14个左右需要作为参数传入的参数。这将指导您的代码,以便为参数化存储过程调用添加参数,每个参数都需要强类型,这将指导您对表的每个列值进行正确的转换。您还应该创建一个C类,该类将所有表列值定义为公共属性。请原谅VB.NET,但您会从这个简单的数据访问层D.A.L示例片段中了解到,UpdateOffer可以重命名为AddUpdateOffer,如果是更新,则可以通过将记录id传递给AddUpdate存储过程来检查记录是否存在,如果记录id为null,则存储过程知道执行insert else更新:

 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

正确的方法是构建一个方法,该方法通过为每个项提供一个参数或通过一个类类型来请求它期望的特定值,即:

private void InsertRec(DEL_PurchasesLines1 lineToInsert)
其中DEL_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,一个表中的许多列几乎总是意味着表的设计有问题,但我暂时不谈这个问题。使用第二种方法,您的按钮单击将如下所示:

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++;
    }
}
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和格式化字符串时完全不合适。这有点重要,所以你一定要读一读

我还看到您正在尝试将插入内容分组到单个批次中。这很好,但多亏了连接池,它并没有给你带来多少好处。正确的查询参数化也很难实现。但这并非不可能,因此我现在将向您展示一个使用另一个方法签名的示例,这使它变得更容易:

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();
    }
}