2017-05-30 18 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(最大)文字列のあとには閉じられていない引用符' '。 System.Data.SqlClient.SqlConnection.OnError(SQLException例外、ブールbreakConnection、Action`1 wrapCloseInAction)で

System.Data.SqlClient.SqlInternalConnection.OnError(SQLException例外、ブールbreakConnection、Action`1でSystem.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior、SqlCommandオブジェクトcmdHandler、SqlDataReaderのdataStrでwrapCloseInAction)System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj、ブールcallerHasConnectionLock、ブールasyncClose)で

EAM、System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTdsでBulkCopySimpleResultSet bulkCopyHandler、TdsParserStateObject stateObj、ブール& DATAREADY)

(文字列methodNameの、ブール非同期、のInt32タイムアウト、ブールasyncWrite)System.Data.SqlClientので

。 ParseColumnCount.DTUpload.C​​SVでSqlCommand.InternalExecuteNonQuery System.Data.SqlClient.SqlCommand.ExecuteNonQueryで(TaskCompletionSource`1完了、文字列methodNameの、ブールsendToPipe、のInt32タイムアウト、ブールasyncWrite)

()

CでUploadCode():\ ParseColumnCount \ DTUpload.cs:ライン66

ClientConnectionId:********************
エラー番号:102、状態: **************
ルーティング先:1、クラス:ルーティングする前に15

ClientConnectionId *****************

提案された変更を作ったし、今

SYSTEM.DAT

を取得していますa.SqlClient.SqlException(0x80131904): 'U'付近の構文が正しくありません。

文字列の後に囲まれていない引用符 ')DROP TABLE [dbo]。 [Compensation.csv]テーブルの作成。[補償。NVARCHAR(最大)、["年俸]" ID "NVARCHAR(最大)、["年俸] "["部門ID "] NVARCHAR(最大)、["ホーム部門 コード[雇用プロファイル] "] NVARCHAR(max)、["Regular Pay Rate Amount"] NVARCHAR(max)、["標準 時間"] NVARCHAR(最大)、["グレードコードを支払う]、NVARCHAR(最大)、[" を支払う] "NVARCHAR (最大)、[補償変更理由コード] NVARCHAR(最大)、[補償変更理由説明] NVARCHAR(最大)) '。

+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 

が問題を参照してください? Oは、単一引用符が続いているので、この場合は、query

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

が取り込まれます限り、SQLに関しては、引用符は、ハリーOで終わりました。 Brianの後に見積もりを見つけたときには、見積りのない開始見積りが見つかるため、エラーになります。

入力を単一引用符でスクラブしてエスケープする必要があります。 SQLサーバーでは、このように、replacing them with double single quotesによってそれらをエスケープ:

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

その後query有効なSQLです

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

を取得します。

他の(より良い)オプションは、ストアドプロシージャを使用して値を挿入し、その場でSQL文を構成するのではなく、文字列をパラメータにバインドすることです。あなたがそうするなら、何かを脱出する必要はありません。

+0

良い[オフィシャル](Bobby Tables)(https://www.xkcd.com/327/)が再び襲います。 –

+0

修正プログラムが提案された後も同様のエラーが表示されます。 – JLM

関連する問題