2017-05-30 62 views
0

我有這個代碼,它試圖將.csv文件加載到SQL Server數據庫並動態創建表。我看到它說有一個語法錯誤和一個未封閉的引號,但我沒有看到它。有任何想法嗎?將csv文件加載到SQL Server數據庫中導致出錯

class DTUpload 
{ 
    public static void CSVUploadCode() 
    { 
     string datetime = DateTime.Now.ToString("yyyyMMddHHmmss"); 
     string LogFolder = @"C:\Log"; 

     try 
     { 
      // Declare Variables and provide values 
      string SourceFolderPath = @"C:\Old\"; 
      string FileExtension = "*.csv"; 
      string FileDelimiter = ","; 
      string ColumnsDataType = "NVARCHAR(max)"; 
      string SchemaName = "dbo"; 

      // Get files from folder 
      string[] fileEntries = Directory.GetFiles(SourceFolderPath, "*" + FileExtension); 

      foreach (string fileName in fileEntries) 
      { 
       // Create Connection to SQL Server in which you would like to create tables and load data 
       SqlConnection SQLConnection = new SqlConnection(); 
       SQLConnection.ConnectionString = "Data Source = *******; Initial Catalog = *******; User id=*******;" + "Password=*********;"; 

       // Writing Data of File Into Table 
       string TableName = ""; 
       int counter = 0; 
       string line; 
       string ColumnList = ""; 

       System.IO.StreamReader SourceFile = new System.IO.StreamReader(fileName); 

       SQLConnection.Open(); 

       while ((line = SourceFile.ReadLine()) != null) 
       { 
        if (counter == 0) 
        { 
         // Read the header and prepare create table statement 
         ColumnList = "[" + line.Replace(FileDelimiter, "],[") + "]"; 
         TableName = (((fileName.Replace(SourceFolderPath, "")).Replace(FileExtension, "")).Replace("\\", "")); 
         string CreateTableStatement = "IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[" + SchemaName + "]."; 
         CreateTableStatement += "[" + TableName + "]')"; 
         CreateTableStatement += " AND type in (N'U'))DROP TABLE [" + SchemaName + "]."; 
         CreateTableStatement += "[" + TableName + "] Create Table " + SchemaName + ".[" + TableName + "]"; 
         CreateTableStatement += "([" + line.Replace(FileDelimiter, "] " + ColumnsDataType + ",[") + "] " + ColumnsDataType + ")"; 
         SqlCommand CreateTableCmd = new SqlCommand(CreateTableStatement, SQLConnection); 
         CreateTableCmd.ExecuteNonQuery(); 
        } 
        else 
        { 
         // Prepare Insert Statement and execute to insert data 
         string query = "Insert into " + SchemaName + ".[" + TableName + "] (" + ColumnList + ") "; 
         query += "VALUES('" + line.Replace(FileDelimiter, "','") + "')"; 

         SqlCommand SQLCmd = new SqlCommand(query, SQLConnection); 
         SQLCmd.ExecuteNonQuery(); 
        } 

        counter++; 
       } 

       SourceFile.Close(); 
       SQLConnection.Close(); 
      } 
     } 
     catch (Exception exception) 
     { 
      // Create Log File for Errors 
      using (StreamWriter sw = File.CreateText(LogFolder 
       + "\\" + "ErrorLog_" + datetime + ".log")) 
      { 
       sw.WriteLine(exception.ToString()); 
      } 
     } 
    } 
} 

這是錯誤消息我得到:

System.Data.SqlClient.SqlException(0x80131904):近 '年度' 的語法不正確。

字符串'] NVARCHAR(max))'之後未使用引號。

在System.Data.SqlClient.SqlConnection.OnError(SqlException異常,布爾breakConnection,Action`1 wrapCloseInAction)

在System.Data.SqlClient.SqlInternalConnection.OnError(SqlException異常,布爾breakConnection,Action`1 wrapCloseInAction)

在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,布爾callerHasConnectionLock,布爾asyncClose)

在System.Data.SqlClient.TdsParser.TryRun(runBehavior runBehavior,SqlCommand的cmdHandler,SqlDataReader的dataStr EAM,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,布爾& dataReady)

在System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(字符串方法名,布爾異步,的Int32超時,布爾asyncWrite)

在System.Data.SqlClient的。 SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1完成,字符串方法名,布爾sendToPipe,的Int32超時,布爾asyncWrite)

在System.Data.SqlClient.SqlCommand.ExecuteNonQuery()

在ParseColumnCount.DTUpload.C​​SV C:\ ParseColumnCount \ DTUpload.cs中的UploadCode():第66行

ClientConnectionId:********************
錯誤編號:102,狀態: 1,類別:15

路由前的ClientConnectionId:**************
路由目標:*****************

所做的修改建議,現在我越來越

的system.dat a.SqlClient.SqlException(0x80131904):'U'附近的語法不正確。

字符串')DROP TABLE [dbo]之後未使用引號。 [Compensation.csv]創建表dbo。[補償。csv]([「Associate ID」] NVARCHAR(max),[「Position ID」] NVARCHAR(max),[「Home Department Code [Employment Profile]」] NVARCHAR(max),[「Annual Salary」] NVARCHAR(max),[「固定工資率金額」] NVARCHAR(max),[「標準 工時」] NVARCHAR(max),[「工資等級代碼」] NVARCHAR(max),[「付款 頻率」] NVARCHAR (max),[「補償更改原因代碼」] NVARCHAR(max),[「補償更改原因描述」] NVARCHAR(max))''。

+0

'CreateTableStatement + =「[」+ TableName +「]')」;',最後刪除單引號。 – Gusman

+0

你應該嘗試給我們你正在嘗試執行的SQL。我們不知道您的CSV文件 – TryingToImprove

+2

您也可以嘗試使用Console.WriteLine(CreateTableStatement)來查看格式化的sql語句的樣子。或System.Diagnostics.Debug.WriteLine(如果它不是控制檯應用程序的一部分)。 –

回答

2

這個代碼看看:

query += "VALUES('" + line.Replace(FileDelimiter, "','") + "')"; 

line想象不同的值。

如果它包含類似

John Smith,Dick Brain,Harry Chest 

然後你會被罰款。

但是如果它包含

John Smith,Dick Brain,Harry O'Brian 

看這個問題?在這種情況下,query將會逐漸加入

VALUES('John Smith,Dick brain,Harry O'Brian') 

至於SQL而言,與哈里Ø結束,因爲O的後跟一個單引號的報價。當它出現在Brian之後的報價中時,它找到一個沒有收盤報價的開盤報價,因此出現了錯誤。

您需要清理單引號的輸入內容並將其轉義。在SQL Server中,您可以通過replacing them with double single quotes逃避他們,就像這樣:

line = line.Replace("'","''"); 
query += "VALUES('" + line.Replace(FileDelimiter, "','") + "')"; 

然後query將得到

VALUES('John Smith,Dick brain,Harry O''Brian') 

這是有效的SQL。

其他(更好)選項是使用存儲過程插入值,並將該字符串綁定到參數,而不是即時構建SQL語句。如果你這樣做,你將不必逃避任何事情。

+0

Good'ole [Bobby Tables](https://www.xkcd.com/327/)再次出現。 –

+0

建議修復後仍顯示類似錯誤。 – JLM

相關問題