在批量插入语句中将varchar转换为datetime的问题

时间:2015-02-16 07:36:37

标签: c# sql-server linq datetime

直到现在,这一切都很好。我没有改变任何代码。

好的,下面的代码是使用linq构建一个批量插入语句,类似于你在SQL中这样做的方式

insert into table1 (First,Last) 
values 
 ('Fred','Smith'),
 ('John','Smith'),
 ('Michael','Smith'),
 ('Robert','Smith');

我的代码userImages是一个图像列表

// build the bulk insert statement.
var tempStatement = userImages.Aggregate(string.Empty, (current, item) => current + string.Format("({0},'{1}','{2}',{3},'{4}',{5}),", userId, item.ImageName, item.ImageUrl, 1, DateTime.Now, "NULL"));

// We now need to trim the last comma off the end, other wise we will get a syntax error in sql.
var extension = tempStatement.Substring(0, tempStatement.Length - 1);

using (var sqlCon = new SqlConnection(Con.ReturnDatabaseConnection()))
{
   var query = @"
                INSERT INTO [User].Images

                (UserId, FileName, ImageUrl, Active, CreatedDate, DeletedDate)

                VALUES
                      " + extension;

  sqlCon.Query(query);
}

当我在using语句上设置断点并查看var extension时,这就是生成的内容

(1247,'o7maxqx3w3yvjtgjivpq','https://res.location.com/dncu6pqpm/image/upload/v1424071993/o7maxqx3w3yvjtgjivpq.png',1,'16/02/2015 07:33:28',NULL)

但是将varchar转换为datetime错误

这工作得非常好,所以我不确定如何继续,我确实要求帮助设置这个,因为这里提出了一个问题

Bulk Insert statement, Look at the answer

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

首先,SQL语句是一个普通的INSERT,而不是一个BULK INSERT。 BULK INSERT用于尽快将数据从文件加载到数据库中。此代码只是尝试添加单个值。

其次,您使用字符串连接来传递值,从而导致意外的十进制和日期值转换,更不用说将代码暴露给SQL注入攻击了。这也会损害性能,因为服务器每次都必须重新编译语句。

您应该使用参数化查询来完全避免转换,提高性能避免注入攻击。

你没有提到你正在使用的ORM(LINQ是查询语言,而不是执行函数),但这是你用普通ADO.NET编写参数化查询的方法:

var sql="INSERT INTO [User].Images (UserId, FileName, ImageUrl, Active, CreatedDate, DeletedDate) " + 
        "VALUES (@userid,@file,@image,@active,@created,@deleted)";
var sqlCmd=new SqlCommand(sqlCon,sql);
sqlCmd.AddWithValue("@userid",userId);
sqlCmd.AddWithValue("@filename",imageName);
sqlCmd.AddWithValue("@active",1);
sqlCmd.AddWithValue("@created",DateTime.Now);
sqlCmd.AddWithValue("@deleted",DBNull.Value);

sqlCon.Open();
sqlCmd.ExecuteNonScalar();

使用ORM执行此操作更加容易,因为ORM将在您保存新对象时生成参数化查询。您只需使用新值创建新对象,并使用ORM的持久性方法保存它。

在Dapper.NET中,等效于:

var sql="INSERT INTO [User].Images (UserId, FileName, ImageUrl, Active, CreatedDate, DeletedDate) " + 
        "VALUES (@userid,@file,@image,@active,@created,@deleted)";
sqlCon.Execute(sql,new {
    userid=userId,
    filename=imageName,
    active=1,
    created=DateTime.Now,
    deleted=null
});

Dapper.NET可以同时处理多个项目。假设你有一个DTO列表,你可以执行:

var sql="INSERT INTO [User].Images (UserId, FileName, ImageUrl, Active, CreatedDate, DeletedDate) " + 
        "VALUES (@userid,@file,@image,@active,@created,@deleted)";
sqlCon.Execute(sql,myListOfDTOs);