我已经做了一些研究"用C#将大量数据插入数据库的麻烦方式",然后很多人建议我使用SqlBulkCopy.在我尝试之后,它真的让我很惊讶.毫无疑问,SqlBulkCopy非常快.看来SqlBulkCopy是插入数据(特别是大数据)的完美方式.但是为什么我们不要一直使用它.使用SqlBulkCopy有什么缺点吗?
我有一个DataTable大约有100,000条记录的ADO.NET .在此表中有一列 xyID没有值,因为该列是IDENTITY在我的SQL Server数据库中自动生成的.
我需要为其他进程检索生成的ID.我正在寻找一种方法来批量复制DataTable到SQL Server数据库,并在相同的"步骤"内"填充"我DataTable生成的ID.
如何使用SqlBulkCopy类检索插入表中的记录的标识值?
我正在使用SqlBulkCopy两个不同列的SQL Server 2008(将一些数据从prod服务器移动到dev).所以想要跳过一些尚未存在/尚未删除的列.
我怎样才能做到这一点?一些技巧ColumnMappings?
编辑:
我做下一个:
DataTable table = new DataTable();
using (var adapter = new SqlDataAdapter(sourceCommand))
{
adapter.Fill(table);
}
table.Columns
.OfType<DataColumn>()
.ForEach(c => bulk.ColumnMappings.Add(
new SqlBulkCopyColumnMapping(c.ColumnName, c.ColumnName)));
bulk.WriteToServer(table)
Run Code Online (Sandbox Code Playgroud)
得到:
给定的ColumnMapping与源或目标中的任何列都不匹配.
我们正在导入一个csv文件,CSVReader然后使用SqlBulkCopy该数据插入SQL Server.这段代码对我们很有用,而且非常简单,但是想知道是否有更快的方法(我们的一些文件有100000行)也不会太复杂?
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
SqlTransaction transaction = conn.BeginTransaction();
try
{
using (TextReader reader = File.OpenText(sourceFileLocation))
{
CsvReader csv = new CsvReader(reader, true);
SqlBulkCopy copy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity, transaction);
copy.DestinationTableName = reportType.ToString();
copy.WriteToServer(csv);
transaction.Commit();
}
}
catch (Exception ex)
{
transaction.Rollback();
success = false;
SendFileImportErrorEmail(Path.GetFileName(sourceFileLocation), ex.Message);
}
finally
{
conn.Close();
}
Run Code Online (Sandbox Code Playgroud) 有没有办法使用SqlBulkCopy而不将数据转换为DataTable?我在RAM中有一个对象列表(List),我真的不想使用更多的内存来创建DataTable.是否可以在List上实现IDataReader?
谢谢!
我需要计算来自SqlBulkCopy的顺序超时异常.为了测试这一点,我使用外部应用程序启动事务并锁定目标表.
只有在第一次调用时,SqlBulkCopy会在预期时抛出超时异常.我们尝试过使用外部连接和事务,以及使用连接字符串和内部事务.使用外部连接和事务,无限等待从未打开连接或开始或提交事务,但总是在.WriteToServer().
是否有一些方法SqlBulkCopy.WriteToServer()可以在达到.BulkCopyTimeout极限时可靠地抛出超时异常?
public void BulkCopy(string connectionString, DataTable table, int bulkTimeout)
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
connectionString,
SqlBulkCopyOptions.UseInternalTransaction))
{
bulkCopy.BulkCopyTimeout = bulkTimeout;//e.g. 120 sec.
//... fill with data, map columns...
bulkCopy.WriteToServer(table);
// ^^^^ waits indefinitely, doesn't throw until *after*
// the lock is released.
}
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢让异常冒泡而不是在using块的范围内处理它们,但我总是可以重新抛出.非常感谢任何见解.
更新1:
仍然没有决议.虽然发现了有趣的行为 - 正常的SqlCommand会在同一个锁中抛出一个TimeoutException,导致SqlBulkCopy.WriteToServer方法无限期挂起.
以下是我们尝试过的方法 - 这些方法都失败了 - 让SqlBulkCopy.WriteToServer在预期时始终如一地抛出超时:
现在,作为一种解决方法,我交替使用a)将WriteToServer调用放在异步包装器中,以便我自己计时,b)只调用WriteToServer一次; 超时后,等到常规SqlCommand 成功再次尝试WriteToServer之前.使用这些方法,我至少能够控制执行流程.
就在一个bulkinsert(SqlBulkCopy)之前,我看到了一个
excec sp_tablecollations_100 N'.tb_tablename'
Run Code Online (Sandbox Code Playgroud)
在探查器中
这是做什么的?这是问题的标志还是正常的?
谢谢你的帮助
更新
之后的插件插入显示插入语句中的COLLATION.它运行正常,只是想知道这是"正常行为"还是批量插入中的COLLATE以某种方式影响性能?
insert bulk tb_dvr_patient ([geboortejaar] VarChar(4) COLLATE Latin1_General_CI_AS,...
Run Code Online (Sandbox Code Playgroud) 我正在尝试批量复制DataTable包含以下列的内容:
System.Int32System.String使用以下列进入SQL数据库:
intgeometry谁能建议最好的方法来做到这一点?
一些测试代码,如果它有帮助......
DataTable dataTable = new DataTable();
dataTable.Columns.Add("ID", typeof(Int32));
dataTable.Columns.Add("Geom", typeof(String));
dataTable.Rows.Add(1, "POINT('20,20')");
dataTable.Rows.Add(1, "POINT('40,25')");
dataTable.Rows.Add(1, "POINT('60,30')");
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(connection);
sqlBulkCopy.DestinationTableName = "MySpatialDataTable";
sqlBulkCopy.WriteToServer(dataTable);
Run Code Online (Sandbox Code Playgroud)
我的原始帖子未能解释执行上述操作会导致抛出以下异常.
InvalidOperationException:数据源中String类型的给定值无法转换为指定目标列的类型udt.
我假设从这里SqlBulkCopy不知道geometry列类型,因此不知道如何从a转换为它string.谁能证实这一点?
我正在尝试SqlBulkCopy使用SQL Server管理导入导出向导创建的flatfiles中的类进行批量插入.这些文件以逗号分隔.
文件中的一行可能如下所示:
{DCAD82A9-32EC-4351-BEDC-2F8291B40AB3} ,, {ca91e768-072d-4e30-aaf1-bfe32c24008f},900001:1792756,900001:1792757,basladdning,2011-04-29 02:54:15.380000000,basladdning,2011- 04-29 02:54:15.380000000,{20A3C50E-8029-41DE-86F1-DDCDB9A78BA5}
我得到的错误是:
System.InvalidOperationException未处理
Message =数据源中String类型的给定值无法转换为指定目标列的uniqueidentifier类型.
所以问题是从字符串转换为GUID.
我尝试过以下方法:
有什么建议?在''是的平面文件中,是一个也有Guid作为数据类型的列.该列为NULL,向导将其导出为''.这可能是问题吗?
代码:
using (var file = new StreamReader(filePath))
using (var csv = new CsvReader(file, false))
using (var bcp = new SqlBulkCopy(CreateConnectionString()))
{
bcp.DestinationTableName = "table";
bcp.WriteToServer(csv);
}
Run Code Online (Sandbox Code Playgroud)
表定义:
CREATE TABLE [beata].[T_FeatureInstance](
[FeatureInstanceId] [uniqueidentifier] NOT NULL,
[FeatureInstanceParentId] [uniqueidentifier] NULL,
[FeatureTypeAliasId] [uniqueidentifier] NOT NULL,
[Uuid] [varchar](1000) NOT NULL,
[VersionId] [varchar](50) NOT NULL,
[SkapadAv] [varchar](255) NULL,
[Skapad] [datetime] NOT NULL,
[UppdateradAv] [varchar](255) NOT …Run Code Online (Sandbox Code Playgroud) 我使用以下代码批量插入数据表到我的SQL表:
// Set up the bulk copy object.
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(destinationConnection.Connection))
{
bulkCopy.DestinationTableName =
Constants.ReportDataTable;
// Write from the source to the destination.
DataTable dtBulk = GetDatatableInReportDataFormat(dt, objectName, version);
bulkCopy.WriteToServer(dtBulk);//To get the Datatable in the SQL table format
}
Run Code Online (Sandbox Code Playgroud)
我的SQL表中有一个名为"Value"的列,其类型为十进制(28,5).我的问题是一些带有十进制数的值正在被自动舍入,因此我正在失去精度,例如将值0.72768保存为0.72767.
在Datatable中,"Value"列的类型为Double.
任何人都有想法吗?谢谢
sqlbulkcopy ×10
c# ×7
sql-server ×6
.net ×4
ado.net ×1
bulkinsert ×1
database ×1
identity ×1
sql ×1
sqlgeometry ×1
timeout ×1