在批量插入语句中将 varchar 转换为日期时间
Issue converting varchar to datetime in bulk insert statement
直到刚才,它都运行良好。我从来没有更改过任何代码。
好的,下面的代码所做的是使用 linq a 构造一个批量插入语句,类似于您在 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 扩展时,这就是生成的内容
(1247,'o7maxqx3w3yvjtgjivpq','https://res.location.com/dncu6pqpm/image/upload/v1424071993/o7maxqx3w3yvjtgjivpq.png',1,'16/02/2015 07:33:28',NULL)
但将 varchar 转换为 datetime 时出错
这工作得很好,所以我不确定如何继续,我确实寻求帮助设置它,因为这里提出了一个问题
如有任何帮助,我们将不胜感激。
首先,SQL 语句是普通 INSERT,而不是 BULK INSERT。 BULK INSERT 用于尽快将文件中的数据加载到数据库中。此代码仅尝试添加单个值。
其次,您使用字符串连接来传递值,导致小数和日期值的意外转换,更不用说将您的代码暴露给 SQL 注入攻击。这也会损害性能,因为服务器每次都必须重新编译语句。
您应该使用参数化查询来完全避免转换,提高性能并且避免注入攻击。
您没有提到您使用的是什么 ORM(LINQ 是查询语言,而不是执行函数),但这就是您可以使用普通 ADO.NET:[=13= 编写参数化查询的方式]
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);
直到刚才,它都运行良好。我从来没有更改过任何代码。
好的,下面的代码所做的是使用 linq a 构造一个批量插入语句,类似于您在 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 扩展时,这就是生成的内容
(1247,'o7maxqx3w3yvjtgjivpq','https://res.location.com/dncu6pqpm/image/upload/v1424071993/o7maxqx3w3yvjtgjivpq.png',1,'16/02/2015 07:33:28',NULL)
但将 varchar 转换为 datetime 时出错
这工作得很好,所以我不确定如何继续,我确实寻求帮助设置它,因为这里提出了一个问题
如有任何帮助,我们将不胜感激。
首先,SQL 语句是普通 INSERT,而不是 BULK INSERT。 BULK INSERT 用于尽快将文件中的数据加载到数据库中。此代码仅尝试添加单个值。
其次,您使用字符串连接来传递值,导致小数和日期值的意外转换,更不用说将您的代码暴露给 SQL 注入攻击。这也会损害性能,因为服务器每次都必须重新编译语句。
您应该使用参数化查询来完全避免转换,提高性能并且避免注入攻击。
您没有提到您使用的是什么 ORM(LINQ 是查询语言,而不是执行函数),但这就是您可以使用普通 ADO.NET:[=13= 编写参数化查询的方式]
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);