67

で次のエラーが発生しcmd.ExecuteNonQueryます。

「ExecuteNonQueryでは、コマンドに割り当てられた接続が保留中のローカルトランザクションにある場合、コマンドにトランザクションが必要です。コマンドのTransactionプロパティが初期化されていません。」

これが私のコードです:

  //if (hdRefresh.Value.Length > done.Value.Length || done.Value == "1")
    //{
    //    //Write Your Add Customer Code here > Response.Write("true") 
    //    done.Value = hdRefresh.Value;
    //}
    //else
    //{
    //    Response.Redirect("~/Cashier/BTBill.aspx");
    //    return;
    //}

    if (IsClosedToDay())
    {
        ScriptManager.RegisterClientScriptBlock(Page, typeof(Page), "Warning", "<script>alert('Day Closing has been Performed ')</script>", false);
        return;
    }

    DateTime dateFeomDB = getdate();
    // by atizaz
    if (HDD.Value == "" || HDD.Value == null)
    {
        ScriptManager.RegisterClientScriptBlock(Page, typeof(Page), "Warning", "<script>alert('No Transaction Found')</script>", false);
        return;
    }
    //
    SqlConnection scon = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLCONN"].ToString());
    Common.BillTransaction bill1 = new Common.BillTransaction();
    ProcessUpdateBalandUnAuthBal insertBalance = new ProcessUpdateBalandUnAuthBal();
    Common.Currency currencyy = new Common.Currency();
    ProcessAuthorizeTokenByBillNo authorize = new ProcessAuthorizeTokenByBillNo();
    BillTransaction bill = new BillTransaction();
    scon.Open();
    SqlTransaction sqlTrans = scon.BeginTransaction();
    try
    {
        string strforxml = HDD.Value;
        XmlDocument docXml = new XmlDocument();


        #region Read In To Sender Controlls

        #region Common Information
        Contact con = new Contact();
        con.Title = ddlTitle.SelectedItem.Text;
        con.FirstName = TextBox1.Text.Trim();
        con.LastName = TextBox9.Text.Trim();
        con.ConTactNo = txtCell.Text == "" ? SqlString.Null : txtCell.Text;
        con.Country = ddlCountry.SelectedItem.Text;
        con.CustomerType = ddlCustomerType.SelectedItem.Text;
        con.CustTypeID = int.Parse(ddlCustomerType.SelectedValue);
        con.CountryID = Int32.Parse(ddlCountry.SelectedValue);
        con.sqlTransaction = sqlTrans;
        if (Scitytxt.Value != "")
        {
            try
            {
                con.City = Scitytxt.Value;
                con.CityID = Int32.Parse(Scityval.Value);
            }
            catch (Exception)
            { }
        }
        else
        {
            con.City = SqlString.Null;// Scitytxt.Value;
            con.CityID = SqlInt32.Null;// Int32.Parse(Scityval.Value);
            con.Address = "";
        }
        //con.City = ddlCity.SelectedItem.Text;
        //con.CityID = int.Parse(ddlCity.SelectedValue);
        con.Address = TextBox10.Text;
        #endregion

        #region Check For NIC and Passport

        if (txtNIC.Text != "" || txtPassport.Text != "")
        {
            SqlDataReader rdrsender;

            if (txtNIC.Text != "")
            {
                con.NIC = txtNIC.Text;
            }
            else
            {
                con.NIC = SqlString.Null;
            }
            if (txtPassport.Text != "")
            {
                con.Passport = txtPassport.Text;
            }
            else
            {
                con.Passport = SqlString.Null;
            }
            ProcessSearchContactInContactInfo srchSender = new ProcessSearchContactInContactInfo();
            srchSender.Contact = con;
            srchSender.Invokewith5parameters();
            rdrsender = srchSender.ResultSet;

            #region If record Doesnot Exist In response of NIC Passport
            if (!rdrsender.Read())
            {
                rdrsender.Close();
                rdrsender.Dispose();
                //  con.sqlTransaction = sqlTrans;
                ProcessAddContact InsertnewSenderInfo = new ProcessAddContact();
                // InsertnewSenderInfo.sqlTransaction = sqlTrans;
                InsertnewSenderInfo.Contact = con;
                InsertnewSenderInfo.Invoke();

                //  sender1 = InsertnewSenderInfo.ResultSet;
                //  Sender_ID.Value = sender1[13].ToString();
            }
            #endregion
            #region If Record Exists
            else
            {
                con.CustomerID = Int32.Parse(rdrsender["Customer_ID"].ToString());
                rdrsender.Close();
                rdrsender.Dispose();
            }
            #endregion
        }
        #endregion

        #region If Customer Donot Have NIC And/OR Passport
        else// this executes when both Pasport and NIC are Null
        {
            con.NIC = SqlString.Null;
            con.Passport = SqlString.Null;
            ProcessAddContact InsertnewSenderInfo = new ProcessAddContact();
            InsertnewSenderInfo.Contact = con;
            InsertnewSenderInfo.Invoke();

            DataSet ds = new DataSet();
            int a = con.CustomerID;
            StringReader inforeader = new StringReader("<CusTable><CusInfo><Relation_Type></Relation_Type><HusbandFather_Name></HusbandFather_Name><Address_Present></Address_Present><Address_Other></Address_Other><Phone_No_Office></Phone_No_Office><Cell_No></Cell_No><Fax_No></Fax_No><Date_Of_Birth></Date_Of_Birth><NTN_No></NTN_No><Nationality></Nationality><Occupation></Occupation><Relation_With_Financial_Institution></Relation_With_Financial_Institution><Other_Relation_With_Financial_Institution></Other_Relation_With_Financial_Institution><Business_Relation></Business_Relation></CusInfo></CusTable>");
            ds.ReadXml(inforeader);
            ds.GetXml();
            SqlCommand cmd = new SqlCommand("update Contact_Info set CustInfo=" + ds.GetXml() + " WHERE Customer_ID=" + a + "", scon);
            cmd.ExecuteNonQuery();

            //  sender1 = InsertnewSenderInfo.ResultSet;
            //  Sender_ID.Value = sender1[13].ToString();
        }

コードの問題点とその解決方法を教えてください。

4

3 に答える 3

109

この行を変更する必要があります

SqlCommand cmd = new SqlCommand("update Contact_Info set CustInfo=" + ds.GetXml() + 
                                " WHERE Customer_ID=" + a + "", scon);

この上

SqlCommand cmd = new SqlCommand("update Contact_Info set CustInfo=" + ds.GetXml() + 
                  " WHERE Customer_ID=" + a + "", scon, sqlTrans);

エラーメッセージは問題を正確に示しています。コードがその行に到達する前に、トランザクションを開いており、エラーの時点でまだ開いています

.....
scon.Open();       
SqlTransaction sqlTrans = scon.BeginTransaction();
.....       

これで、接続でトランザクションが開かれているときに実行されるすべての SqlCommand に、これを通知する必要があります。トランザクションは、フレームワークによって自動的に設定されません。

上記で説明したように、SqlCommand コンストラクターを使用するかcmd.Transaction、コマンドを実行する前にプロパティを設定できます。

警告 1

接続自体から直接 SqlCommand を作成する場合でも、現在のコマンドのトランザクションを設定する必要があります。

   SqlCommand cmd = scon.CreateCommand();
   cmd.Transaction = sqlTrans; // Required when inside a transaction 

警告 2

クエリ テキストを使用してデータベースで更新/挿入/削除/選択する場合は、文字列連結の使用を絶対に避けてください。パラメータを使用します。これにより、奇妙な文字や無効な文字の問題が解消され、最も重要なこととして、SqlInjection 攻撃が防止されます。

string sqlText = "update Contact_Info set CustInfo=@info WHERE Customer_ID=@id";
SqlCommand cmd = new SqlCommand(sqlText, scon, sqlTrans);  
cmd.Parameters.AddWithValue("@info", ds.GetXml());
cmd.Parameters.AddWithValue("@id",a);
cmd.ExecuteNonQuery();  

また、別の推奨事項は、AddWithValue を使用しないことです。便利ですが、この方法には、私の回答で説明されているように多くの問題があります。

于 2012-05-18T08:10:30.297 に答える
32

を呼び出す前にコミットされていないトランザクションを開始しましたcmd.ExecuteNonQuery()

cmd.Transaction = sqlTrans;直前に書き留めてくださいcmd.ExecuteNonQuery();

NowExecuteNonQuery()が同じトランザクションで実行され、同じトランザクションでデータベースに対して行われたすべての変更を確認できるようになります。

于 2012-05-18T07:52:50.407 に答える
0

このコードがある場合:

SqlTransaction sqlTrans = scon.BeginTransaction();

次に、これも必要です:

cmd.Transaction = sqlTrans;

彼らは一緒に働きます。

于 2021-10-12T01:13:26.560 に答える