2013-07-25 63 views
0

我使用下面的代碼更新我的某個Windows窗體上的商業信息。當用戶在txtBusName提出的商戶名稱類似「桑迪的地方」我收到Incorrect Syntax near ';'. Unclosed quotation mark after the character string ';'.SQL語法錯誤:刪除/拒絕撇號?

什麼是處理這個問題的最好方法?

conn = new SqlConnection(connString); 
conn.Open(); 
SqlCommand cmd = conn.CreateCommand(); 

mskZip.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals; 
string zip = mskZip.Text; 
mskZip.TextMaskFormat = MaskFormat.IncludeLiterals; 
mskMailZip.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals; 
string mailzip = mskMailZip.Text; 
mskMailZip.TextMaskFormat = MaskFormat.IncludeLiterals; 
mskPhone.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals; 
string phone = mskPhone.Text; 
mskPhone.TextMaskFormat = MaskFormat.IncludeLiterals; 
mskFax.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals; 
string fax = mskFax.Text; 
mskFax.TextMaskFormat = MaskFormat.IncludeLiterals; 


cmd.CommandText = "Update Business SET Name='" + txtBusName.Text + "', ContactName='" + txtContName.Text + 
       "', Address='" + txtAddr1.Text + "', City='" + txtCity.Text + "', State='" + cmbState.Text + "', Zip=" + ((zip=="")?"NULL":zip) + ", " + 
       "MailAddress='" + txtMailAddr1.Text + "', MailCity='" + txtMailCity.Text + "', MailState='" + cmbMailState.Text + 
       "', MailZipcode=" + ((mailzip == "") ? "NULL" : mailzip) + ", Latitude=" + ((txtLat.Text == "") ? "NULL" : txtLat.Text) + ", Longitude=" + ((txtLong.Text == "") ? "NULL" : txtLong.Text) + ", Phone=" + 
       ((phone == "") ? "NULL" : phone) + ", Fax=" + ((fax == "") ? "NULL" : fax) + ", Email='" + txtEmail.Text + "' " + 
       "WHERE BusinessID=" + busID + " AND Status='A';"; 

cmd.ExecuteNonQuery(); 

MessageBox.Show("Database updated successfully."); 
this.Close(); 
+1

使用參數化查詢 – Steve

+0

@Steve參數化查詢如何協助防止出現問題? –

回答

1

您需要使用parameterized query這樣

cmd.CommandText = 
     "Update Business SET [email protected], [email protected], [email protected], " + 
       "[email protected], [email protected], [email protected], " + 
       "[email protected], [email protected], [email protected], " + 
       "[email protected], [email protected], [email protected], [email protected], " + 
       "[email protected], [email protected] " + 
       "WHERE [email protected] AND Status='A'"; 

cmd.Parameters.AddWithValue("@name", txtBusName.Text); 
cmd.Parameters.AddWithValue("@contact", txtContName.Text); 
cmd.Parameters.AddWithValue("@address", txtAddr1.Text); 
cmd.Parameters.AddWithValue("@city", txtCity.Text); 
cmd.Parameters.AddWithValue("@state", cmbState.Text); 

SqlParameter p1 = cmd.Parameters.Add("@zip", SqlDbType.NVarChar); 
if(zip == "") p1.Value = DBNull.Value; else p1.Value = zip; 

cmd.Parameters.AddWithValue("@mail", txtMailAddr1.Text); 
cmd.Parameters.AddWithValue("@ecity", txtMailCity.Text); 
cmd.Parameters.AddWithValue("@estate", cmbMailState.Text); 

p1 = cmd.Parameters.Add("@ezip", SqlDbType.NVarChar); 
if (mailzip == "") p1.Value = DBNull.Value; else p1.Value = mailzip; 

p1 = cmd.Parameters.Add("@lat", SqlDbType.NVarChar); 
if (txtLat.Text == "") p1.Value = DBNull.Value; else p1.Value = txtLat.Text; 

p1 = cmd.Parameters.Add("@lng", SqlDbType.NVarChar); 
if (txtLong.Text == "") p1.Value = DBNull.Value; else p1.Value = txtLong.Text; 

p1 = cmd.Parameters.Add("@phone", SqlDbType.NVarChar); 
if (phone == "") p1.Value = DBNull.Value; else p1.Value = phone; 

p1 = cmd.Parameters.Add("@fax", SqlDbType.NVarChar); 
if (fax == "") p1.Value = DBNull.Value; else p1.Value = fax; 

cmd.Parameters.AddWithValue("@email", txtEmail.Text); 
cmd.Parameters.AddWithValue("@busID", busID); 

以上鍊接的文章值得一從開始到結束閱讀,但是,要總結,用你讓一個參數化查詢將單引號(以及數字小數和日期文字)格式化爲知道比我更好的框架代碼以及如何處理該字符串的工作,並且以這種方式避免了可能會使數據庫暴露給您的可怕問題黑客攻擊

注意:我不知道應設置爲空的列的實際數據類型,所以我假定它們都是NVARCHAR。如果不是這種情況,那麼應該用適當的值替換SqlDbType。

+0

感謝您的明確示例!我現在可以看到以前代碼的安全問題:SI有一個問題:當我將鼠標懸停在任何'DBNull.Value:...'上時,我有一個紅色標記,上面寫着:「**錯誤:條件類型無法確定表達式,因爲'System.DBNull'和'string'**「之間沒有隱式轉換。 –

+0

是的,我看到問題,現在正在修復 – Steve

+0

看起來像** Zip **是Varchar(15),** MailZipCode ** Varchar(15),** Latitude ** Varchar(20),** Longitude ** Varchar (20),** Phone ** Varchar(25),** Fax ** Varchar(25)。將改變代碼並讓你知道。 –

2

逃避SQL單引號用雙單引號,所以Sandy''s place應該工作。

我強烈建議使用查詢參數而不是將自己的查詢串在一起,這將修復潛在的安全風險(SQL注入)以及最可能的問題,例如引號。

+0

我明白你的意思是關於注射風險。參數化查詢將如何幫助解決此問題? –

+0

因爲它會考慮編碼特殊字符等。 –

1

請使用SqlParameter對象,而不是像那樣的字符串連接。喜歡的東西:

string sql = "Update Business SET [email protected], [email protected], [email protected] WHERE [email protected] AND Status='A';"; 
    System.Data.SqlClient.SqlParameter[] par = new System.Data.SqlClient.SqlParameter[4]; 
    par[0] = new System.Data.SqlClient.SqlParameter("@Name", txtBusName.Text); 
    par[1] = new System.Data.SqlClient.SqlParameter("@ContactName", txtContName.Text); 
    par[2] = new System.Data.SqlClient.SqlParameter("@Address", txtAddr1.Text); 
    par[3] = new System.Data.SqlClient.SqlParameter("@BusinessID", busID); 

     System.Data.SqlClient.SqlCommand com = new System.Data.SqlClient.SqlCommand(sql, SQL_CONNECTION); 
     com.Parameters.AddRange(par); 
     com.ExecuteNonQuery(); 

你有這麼沒有寫他們全部:)

使用這種方法會照顧的特殊字符,如撇號你加使代碼看起來更乾淨,更可讀的參數太多更安全。

+0

感謝您輸入你做了什麼:)但是,如何幫助額外引號的問題呢? –

+0

如果你使用SqlParameter,它會照顧你的特殊字符,如撇號或某些符號(記不起我的頭頂)。 –