2011-07-12 74 views
1

我試圖在稱爲「已處理」的字段中將一個位值(true或false)寫入我的數據庫中。我目前正在試圖通過傳遞布爾值來做到這一點,但我得到一個錯誤,說不能從類型varchar轉換爲位。任何人都可以看到我的邏輯中發生了什麼?將位值寫入數據庫

 protected void CheckBoxProcess_CheckedChanged(object sender, EventArgs e) 
    { 
     bool update; 
     bool trueBool = true; 
     bool falseBool = false; 
     string checkedString = "UPDATE SecureOrders SET processed = '%" + trueBool + "%' WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 
     string uncheckedString = "UPDATE SecureOrders SET processed = '%" + falseBool + "%' WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 
     CheckBox cb = (CheckBox)sender; 
     GridViewRow gvr = (GridViewRow)cb.Parent.Parent; 
     DefaultGrid.SelectedIndex = gvr.RowIndex; 
     update = Convert.ToBoolean(DefaultGrid.SelectedValue); 

     orderByString = orderByList.SelectedItem.Value; 
     fieldString = searchTextBox.Text; 


     System.Configuration.ConnectionStringSettings connectionString; 

     connectionString = rootWebConfig.ConnectionStrings.ConnectionStrings["secureodb"]; 



     // Create an SqlConnection to the database. 
     using (SqlConnection connection = new SqlConnection(connectionString.ToString())) 
     { 
      connection.Open(); 
      SqlCommand checkedCmd = new SqlCommand(checkedString, connection); 
      SqlCommand uncheckedCmd = new SqlCommand(uncheckedString, connection); 
      dataAdapter = new SqlDataAdapter("SELECT * FROM SecureOrders", connection); 

      // create the DataSet 
      dataSet = new DataSet(); 
      // fill the DataSet using our DataAdapter    
      dataAdapter.Fill(dataSet, "SecureOrders"); 

      DataView source = new DataView(dataSet.Tables[0]); 
      DefaultGrid.DataSource = source; 


      if (cb.Checked == true) 
      { 
       checkedCmd.ExecuteNonQuery(); 

      } 
      else 
      { 
       uncheckedCmd.ExecuteNonQuery(); 
      } 

      connection.Close(); 
     } 






    } 
+0

爲什麼不ü保持'int'和''0' 1'? – Sudantha

回答

5

您需要將位字段設置爲10,具體取決於它是true還是false。

所以:

string checkedString = "UPDATE SecureOrders SET processed = 1 WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 
string uncheckedString = "UPDATE SecureOrders SET processed = 0 WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 

而且,正如在評論中提到的,直接從用戶輸入構造SQL語句是犧牲品SQL注入攻擊的最簡單方法。在這些情況下,最好使用參數化查詢(甚至是存儲過程)。

.... 
string checkedString = "UPDATE SecureOrders SET processed = 1 WHERE fName LIKE @p1 AND lName LIKE @p2"; 
string uncheckedString = "UPDATE SecureOrders SET processed = 0 WHERE fName LIKE @p1 AND lName LIKE @p2"; 

然後,您可以創建參數傳遞給你的ExecuteNonQuery調用做,這是你的Convert.ToInt16布爾值

SqlParameter p1 = new SqlParameter("@p1",SqlDbType.Varchar) { Value = string.Format("%{0}%",DefaultGrid.SelectedRow.Cells[2].Text) }; 
SqlParameter p2 = new SqlParameter("@p2",SqlDbType.Varchar) { Value = string.Format("%{0}%",DefaultGrid.SelectedRow.Cells[3].Text) }; 
if (cb.Checked == true) 
{ 
    checkedCmd.Parameters.Add(p1); 
    checkedCmd.Parameters.Add(p2); 
    checkedCmd.ExecuteNonQuery(); 

} 
else 
{ 
    uncheckedCmd.Parameters.Add(p1); 
    uncheckedCmd.Parameters.Add(p2); 
    uncheckedCmd.ExecuteNonQuery(); 
} 
+0

好的,謝謝。這是我有過,但現在我的問題是,它實際上沒有任何內容寫入數據庫...我假設更多的代碼將需要看到的? –

+0

一個問題(我認爲)是您填寫您的DataAdapter你做你的更新...因此由更新所做的任何更改將不會在DataGrid的結果反映了。 – ckramer

+0

我瘋了還是被大家忽略了一個事實,即構建SQL語句的方式是SQL注入漏洞的經典例子?不僅如此,但如果他解決了這個問題,他也會解決這個問題是關於......? – pseudocoder

2

在SQL的比特值是1或0,而不是 '真' 或 '假'。在更新中將「true」和「false」更改爲1和0,您應該沒問題。 (請注意,0和1也沒有引號。)

+0

嗯,我做到了,但之前沒有工作。我想我可以再試一次。 –

+0

它應該工作,確保你沒有引號。 – DaveShaw

+0

的問題是,它實際上沒有任何內容寫入數據庫:/的1和0註冊爲位值精我想,但不會寫出來。 –

0

您的SQL語法錯誤 - 您正在傳遞一個字符串作爲將processed列值設置爲的值,這是您無法執行的操作。

0

最簡單的方法。這將使真/假,0或1.

0

布爾值被連接爲「true」|「false」。嘗試使用三元操作鈕顯示「1」或「0」:

string checkedString = "UPDATE SecureOrders SET processed = '%" + (trueBool ? "1" : "0") + "%' WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 
0

你的SQL語句是不是要設置任何形式的布爾的,它試圖設置文本%True%%False%

由於您將數據庫字段描述爲「位」而不是「布爾」,因此在構建字符串時可能需要使用類似"processed = " + (trueBool ? 1 : 0) + "的內容。但取決於您使用的SQL服務器,您可能能夠脫離processed = " + trueBool + "processed = '" + trueBool + "'之類的東西。

或者,在這種特殊情況下,您可以跳過插值trueBool,並使用完全常量字符串,因爲大多數其他答案都提示過。

另外,順便說一下,請注意,通過將未經檢查的用戶輸入內插到您的SQL語句中,您將爲自己的錯誤和SQL注入敞開大門。例如,如果有人輸入「O'Brian」作爲姓,你將會得到錯誤,並且如果有更多的惡意值選擇,他們可能會改變數據庫中的任何內容。

3

雖然確實如果你注入SQL語句字符串「1」爲真,「0」爲假,你將解決你的問題,解決這個問題的「正確」方法是參數化你的SQL語句和將參數添加到命令對象。然後由框架完成從VB BooleanSqlDbType.Bit的類型轉換。

嘗試:

string sqlString = "UPDATE SecureOrders SET processed = @Processed WHERE fName LIKE '%' + @FirstName + '%' AND lName LIKE '%' + @LastName + '%'"; 

和:

 SqlCommand objCmd = new SqlCommand(sqlString, connection); 
     objCmd.Parameters.AddWithValue("Processed", cb.Checked); 
     objCmd.Parameters.AddWithValue("FirstName", DefaultGrid.SelectedRow.Cells[2].Text); 
     objCmd.Parameters.AddWithValue("LastName", DefaultGrid.SelectedRow.Cells[3].Text); 

最後:

objCmd.ExecuteNonQuery(); 

如果你將要寫入數據驅動的web應用程序是非常重要的,你知道如何避免SQL注入安全漏洞。欲瞭解更多信息:MSDN How To: Protect From SQL Injection in ASP.NET