2010-04-24 46 views
2

實際上我的任務是將csv文件加載到使用c#的sql服務器中,所以我用逗號分隔它我的問題是,某些字段的數據包含撇號和im發射插入查詢將數據加載到sql中,因此它給出錯誤我的代碼如下如何插入數據,如果它包含撇號?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.IO; 
using System.Data.SqlClient; 

namespace tool 
{ 
    public partial class Form1 : Form 
    { 
     StreamReader reader; 
     SqlConnection con; 
     SqlCommand cmd; 
     int count = 0; 
     //int id=0; 
     FileStream fs; 
     string file = null; 
     string file_path = null; 
     SqlCommand sql_del = null; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      OpenFileDialog file1 = new OpenFileDialog(); 
      file1.ShowDialog(); 
      textBox1.Text = file1.FileName.ToString(); 
      file = Path.GetFileName(textBox1.Text); 
      file_path = textBox1.Text; 
      fs = new FileStream(file_path, FileMode.Open, FileAccess.Read); 

     } 

     private void button2_Click(object sender, EventArgs e) 
     { 

       if (file != null) 
        { 
        sql_del = new SqlCommand("Delete From credit_debit1", con); 
        sql_del.ExecuteNonQuery(); 
        reader = new StreamReader(file_path); 
        string line_content = null; 
        string[] items = new string[] { }; 
        while ((line_content = reader.ReadLine()) != null) 
        { 
         if (count >=4680) 
         { 
          items = line_content.Split(','); 
          string region = items[0].Trim('"'); 
          string station = items[1].Trim('"'); 
          string ponumber = items[2].Trim('"'); 
          string invoicenumber = items[3].Trim('"'); 
          string invoicetype = items[4].Trim('"'); 
          string filern = items[5].Trim('"'); 
          string client = items[6].Trim('"'); 
          string origin = items[7].Trim('"'); 
          string destination = items[8].Trim('"'); 
          string agingdate = items[9].Trim('"'); 
          string activitydate = items[10].Trim('"'); 

          if ((invoicenumber == "-") || (string.IsNullOrEmpty(invoicenumber))) 
          { 
           invoicenumber = "null"; 

          } 
          else 
          { 
           invoicenumber = "'" + invoicenumber + "'"; 
          } 


          if ((destination == "-") || (string.IsNullOrEmpty(destination))) 
          { 
           destination = "null"; 

          } 
          else 
          { 
           destination = "'" + destination + "'"; 
          } 

          string vendornumber = items[11].Trim('"'); 

          string vendorname = items[12].Trim('"'); 

          string vendorsite = items[13].Trim('"'); 

          string vendorref = items[14].Trim('"'); 

          string subaccount = items[15].Trim('"'); 

          string osdaye = items[16].Trim('"'); 

          string osaa = items[17].Trim('"'); 


          string osda = items[18].Trim('"'); 

          string our = items[19].Trim('"'); 


          string squery = "INSERT INTO credit_debit1" + 
              "([id],[Region],[Station],[PONumber],[InvoiceNumber],[InvoiceType],[FileRefNumber],[Client],[Origin],[Destination], " + 
              "[AgingDate],[ActivityDate],[VendorNumber],[VendorName],[VendorSite],[VendorRef],[SubAccount],[OSDay],[OSAdvAmt],[OSDisbAmt], " + 
              "[OverUnderRecovery]) " + 
              "VALUES " + 
              "('" + count + "','" + region + "','" + station + "','" + ponumber + "'," + invoicenumber + ",'" + invoicetype + "','" + filern + "','" + client + "','" + origin + "'," + destination + "," + 
              "'" + (string)agingdate.ToString() + "','" + (string)activitydate.ToString() + "','" + vendornumber + "',' " + vendorname + "',' " + vendorsite + "',' " + vendorref + "'," + 
             "'" + subaccount + "','" + osdaye + "','" + osaa + "','" + osda + "','" + our + "') "; 

          cmd = new SqlCommand(squery, con); 
          cmd.CommandTimeout = 1500; 

          cmd.ExecuteNonQuery(); 

         } 
         label2.Text = count.ToString(); 

         Application.DoEvents(); 
         count++; 


        } 


        MessageBox.Show("Process completed"); 
       } 
       else 
       { 
        MessageBox.Show("path select"); 
       } 
     } 









     private void button3_Click(object sender, EventArgs e) 
     { 
      this.Close(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      con = new SqlConnection("Data Source=192.168.50.200;User ID=EGL_TEST;Password=TEST;Initial Catalog=EGL_TEST;"); 
      con.Open(); 
     } 
    } 

} 

vendername字段包含數據(MCCOLLISTER的運輸),所以如何通過在這種情況下SqlParameterCollection.AddWithValue或等效這個數據

回答

6

使用prepared statements。有各種各樣的教程可用於此。

+0

事實上,'AddWithValue'會影響計劃重用,因爲它使用該值來推斷參數長度。最好手動定義arg,明確說明*正確*長度。 – 2010-04-24 08:28:13

-2

你非常調皮的建立你的sql語句,聖誕老人絕對不會在今年訪問你。按照自己的方式進行查詢會打開自己的SQL注入攻擊,有意和無意的,因爲你已經發現了'。

您應該使用參數化查詢字符串或存儲過程。

const string connString = "Data Source=localhost;Initial Catalog=OnlineQuiz;Integrated Security=True"; 

static void Main(string[] args) 
{ 
    string query = string.Format("SELECT * FROM [User] WHERE name like @name"); 

    using (SqlConnection conn = new SqlConnection(connString)) 
    { 
     using (SqlCommand cmd = new SqlCommand(query, conn)) 
     { 
      cmd.Parameters.AddWithValue("@name", "F%"); 

      conn.Open(); 
      using (SqlDataReader reader = cmd.ExecuteReader()) 
      { 

       while (reader.Read()) 
       { 
        Console.WriteLine(reader.GetValue(1)); 
       } 
      } 
     } 
    } 
} 
+0

不回答問題。 – 2010-04-24 06:39:32

+0

是的,「F%」很容易成爲「O%」......更重要的是它演示瞭如何使用參數化查詢來編寫它。 – Felan 2010-04-24 06:46:26

-2

你需要通過添加第二個撇號逃脫撇號:

vendorname = vendorname.Replace("'", "''"); 

免責聲明:編寫原始SQL語句中不使用的參數是很危險的。理想情況下,你應該寫一個完整的SQL INSERT語句與假設參數的,而不將值直接到字符串,將它作爲一個參數:

string parameterizedSQL = "insert into credit_debit1 (id,region,station) values (@count, @region,@station)"; 

SqlCommand cmd = new SqlCommand(parameterizedSQL, con); 
cmd.Parameters.Add("@count", SqlDbType.Int).Value = count; 
cmd.Parameters.Add("@region", SqlDbType.VarChar).Value = region; 
cmd.Parameters.Add("@station", SqlDbType.VarChar).Value = station; 
cmd.ExecuteNonQuery(); 
+0

構建一個像他這樣的查詢不是通過添加撇號來實現的,並且仍然存在問題。 – Felan 2010-04-24 06:29:44

+0

是的,但不要告訴我你的答案將需要更少的時間來實現,或者也是沒有錯誤的。你的回答甚至不包括插入或存儲過程調用。 – 2010-04-24 06:39:07

+0

您可以使用插入查詢輕鬆地替換選擇查詢。而你提出的是錯誤的,因爲它對sql注入攻擊是可以接受的,使用參數化查詢不是。 – Felan 2010-04-24 06:48:22

相關問題