我有这个代码试图将.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))'。
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception,Boolean breakConnection,Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception,Boolean breakConnection,Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName,Boolean async,Int32 timeout,Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion,String methodName,Boolean sendToPipe,Int32 timeout,Boolean asyncWrite)
在System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
在C:\ ParseColumnCount \ DTUpload.cs中的ParseColumnCount.DTUpload.CSVUploadCode():第66行
ClientConnectionId:********************
错误号码:102,状态:1,等级:15路由前的ClientConnectionId:**************
路由目的地:*****************
进行了建议的更改,现在正在进行
System.Data.SqlClient.SqlException(0x80131904):' U'附近的语法不正确。
字符串后的未闭合引号')DROP TABLE [dbo]。 [Compensation.csv]创建表dbo。[Compensation.csv]([" Associate ID"] NVARCHAR(最大),["职位ID"] NVARCHAR(最大),["家庭部门 代码[就业资料]"] NVARCHAR(最高),["年薪"] NVARCHAR(最大),["常规工资额"] NVARCHAR(最大),["标准 小时"] NVARCHAR(最大),["薪酬等级代码"] NVARCHAR(最高),["支付 频率"] NVARCHAR(最大),["赔偿更改原因代码"] NVARCHAR(最大),["薪酬变更原因说明"] NVARCHAR(MAX))'
答案 0 :(得分: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而言,报价以Harry O结束,因为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语句。如果你这样做,你将不必逃避任何事情。