2011-07-12 23 views
1

"処理済み"というフィールドのビット値(trueまたはfalse)をデータベースに書き込もうとしています。私は現在、bool値を渡すことでこれをやろうとしていますが、varchar型からbit型に変換できないというエラーが表示されます。私の論理に何が起こっているのか誰にでも見える?データベースにビット値を書き込む

 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

trueまたはfalseのどちらかによって、ビットフィールドを1または0に設定する必要があります。だから、

また
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インジェクション攻撃の犠牲にする最も簡単な方法です。そのような場合には、常にparamaterizedクエリ(またはStored Procs)を使用することをお勧めします。

.... 
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"; 

あなたはこれを行う最も簡単な方法は、あなたのブール値をConvert.ToInt16することで、あなたのExecuteNonQueryコール

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

1つの問題(私は思う)は、あなたの更新を行う前にあなたのDataAdapterを埋めることです...更新によって行われた変更は、DataGridの結果に反映されません。 – ckramer

+0

私は夢中になっているのですか、あるいはSQL文を構築するこの方法がSQLインジェクションの脆弱性の古典的な例であるという事実を無視していますか?それだけでなく、もし彼がその問題を解決すれば、彼はこの問題についての問題を解決するでしょう...? – pseudocoder

2

SQLでは、ビット値は1または0で、「true」または「false」ではありません。あなたのアップデートで 'true'と 'false'を1と0に変更すればOKです。 (0と1には引用符もありません)

+0

ええ、私はこれをしましたが、以前はうまくいきませんでした。私は再びそれを試すことができると思います。 –

+0

それは正常に動作するはずです。数字の周りに引用符がないことを確認してください。 – DaveShaw

+0

問題は実際にはデータベースに何も書き込んでいないことです。/ 1と0はビット値として登録していると思いますが、書き込みはしません。 –

0

SQL構文が間違っています - 文字列を値として渡して、processed列の値を次のように設定しています。

0

に渡すパラメータを作成することができます。 true/false、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

Trueの場合は "1"、Falseの場合は "0"をSQL文に挿入すると問題は解決しますが、この問題を解決する "適切な"方法はSQL文をパラメータ化することですコマンドオブジェクトにパラメータを追加します。 VB BooleanからSqlDbType.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