我正在使用具有有限权限的数据库用户,使用C#方法将ADO.NET 2.0 SqlBulkCopy对象批量插入到MS SQL 2005数据库中.当我尝试运行该操作时,我收到错误消息:
批量复制失败.用户对表'theTable'没有ALTER TABLE权限.ALTER TABLE权限是必需上批量复制操作的目标表,如果该表具有触发器或检查约束,但
'FIRE_TRIGGERS'还是'CHECK_CONSTRAINTS'散装提示没有被指定为选项,以批量复制命令.
我阅读了一些文档并使用构造函数创建了批量复制对象,该构造函数允许我指定这样的东西:
SqlBulkCopy bc = new SqlBulkCopy(
System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"],
SqlBulkCopyOptions.FireTriggers & SqlBulkCopyOptions.CheckConstraints);
Run Code Online (Sandbox Code Playgroud)
但这并没有改变任何东西 - 我得到了和以前一样的错误信息.我尝试摆弄其他一些SqlBulkCopyOptions值,但没有运气.我真的以为这会解决这个问题,我错过了什么吗?
我在表上向用户授予ALTER后测试了该过程,操作成功.但是,这不适合我的情况.
我正在尝试使用批量插入数据到SQL 2008 SqlBulkCopy.
这是我的表:
IF OBJECT_ID(N'statement', N'U') IS NOT NULL
DROP TABLE [statement]
GO
CREATE TABLE [statement](
[ID] INT IDENTITY(1, 1) NOT NULL,
[date] DATE NOT NULL DEFAULT GETDATE(),
[amount] DECIMAL(14,2) NOT NULL,
CONSTRAINT [PK_statement] PRIMARY KEY CLUSTERED
(
[ID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
private DataTable GetTable()
{
var list = new List<DataColumn>();
list.Add(new DataColumn("amount", typeof(SqlDecimal)));
list.Add(new DataColumn("date", …Run Code Online (Sandbox Code Playgroud) 在Excel表(以transferTable)看完后,我想将数据添加到使用SqlBulkCopy的新表(destinationTable会),但我得到的错误:
Cannot access destination table 'test'
Run Code Online (Sandbox Code Playgroud)
我尝试使用默认的表名并使用方括号,但这不起作用.
有什么建议?
private void writeToDBButton_Click(object sender, EventArgs e) {
MakeTable();
destinationTable.TableName = "test";
testDBDataSet.Tables.Add("test");
// Connects to the sql-server using Connection.cs
SqlConnection connection = Connection.GetConnection();
using (connection) {
connection.Open();
// Uses SqlBulkCopy to copy the data from our transferTable to the destinationTable
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection)) {
bulkCopy.DestinationTableName = destinationTable.TableName;
try {
// Write from the source to the destination.
bulkCopy.WriteToServer(transferTable);
this.dataGridView2.DataSource = destinationTable;
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
connection.Close(); …Run Code Online (Sandbox Code Playgroud) 我试图找出如何使用c#在SQL Server的临时表中提高插入性能.有些人说我应该使用SQLBulkCopy但是我必须做错了,因为它似乎比简单地构建一个SQL插入字符串慢得多.
我使用SQLBulkCopy创建表的代码如下:
public void MakeTable(string tableName, List<string> ids, SqlConnection connection)
{
SqlCommand cmd = new SqlCommand("CREATE TABLE ##" + tableName + " (ID int)", connection);
cmd.ExecuteNonQuery();
DataTable localTempTable = new DataTable(tableName);
DataColumn id = new DataColumn();
id.DataType = System.Type.GetType("System.Int32");
id.ColumnName = "ID";
localTempTable.Columns.Add(id);
foreach (var item in ids)
{
DataRow row = localTempTable.NewRow();
row[0] = item;
localTempTable.Rows.Add(row);
localTempTable.AcceptChanges();
}
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DestinationTableName = "##" + tableName;
bulkCopy.WriteToServer(localTempTable);
}
}
Run Code Online (Sandbox Code Playgroud)
这样我的插入需要很长时间才能运行.我让插件以另一种方式更快地工作:
我将insert位创建为一个字符串,并在我的SQL create temp table语句中加入它: …
是否可以将SqlBulkcopy与Sql Compact Edition一起使用,例如(*.sdf)文件?
我知道它适用于SQL Server 200 Up,但想检查CE兼容性.
如果没有其他人知道在不使用DataSet的情况下将CSV类型文件放入SQL Server CE的最快方法(请点击这里)?
我有大约6500个文件,总和大约17 GB的数据,这是我第一次移动我称之为大量数据的东西.数据位于网络驱动器上,但各个文件相对较小(最大7 MB).
我正在用C#编写程序,如果我使用BULK INSERT而不是SQLBulkCopy,我想知道是否会注意到性能的显着差异.服务器上的表也有一个额外的列,所以如果我使用BULK INSERT,我将不得不使用格式文件,然后为每一行运行UPDATE.
我是新来的论坛,所以如果有更好的方式来问这个问题,请随意提及.
我们已经有一个运行系统来处理所有连接字符串(db2,oracle,MSServer).
目前,我们正在使用ExecuteNonQuery()一些插入.
我们希望通过使用SqlBulkCopy()而不是改进性能ExecuteNonQuery().我们有一些客户拥有超过5000万条记录.
我们不想使用SSIS,因为我们的系统支持多个数据库.
我创建了一个示例项目来测试其性能SqlBulkCopy().我为MSServer创建了一个简单的读取和插入函数
这是小功能:
public void insertIntoSQLServer()
{
using (SqlConnection SourceConnection = new SqlConnection(_sourceConnectionString))
{
//Open the connection to get the data from the source table
SourceConnection.Open();
using (SqlCommand command = new SqlCommand("select * from " + _sourceSchemaName + "." + _sourceTableName + ";", SourceConnection))
{
//Read from the source table
command.CommandTimeout = 2400;
SqlDataReader reader = command.ExecuteReader();
using (SqlConnection …Run Code Online (Sandbox Code Playgroud) 我想通过参数传递特定数据,制作一个可用于所有批量插入的SqlBulkCopy方法.
现在我需要对其中一些进行映射.我不知道如何制作SqlBulkCopyColumnMappingCollection,因为那是我计划传递映射集合并使用它.但是我不知道如何制作它.我不能成为它的新对象.
这就是我现在拥有的.如何添加它做映射把它传递进去?
public void BatchBulkCopy(DataTable dataTable, string DestinationTbl, int batchSize)
{
// Get the DataTable
DataTable dtInsertRows = dataTable;
using (SqlBulkCopy sbc = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.KeepIdentity))
{
sbc.DestinationTableName = DestinationTbl;
// Number of records to be processed in one go
sbc.BatchSize = batchSize;
// Finally write to server
sbc.WriteToServer(dtInsertRows);
}
}
Run Code Online (Sandbox Code Playgroud) 使用的软件:Windows 7 64位Ultimate,.Net 4,SQL Server 2008 R2.
select @@ version返回:
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1617.0 (X64) Apr 22 2011 19:23:43 Copyright (c) Microsoft Corporation Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)
Run Code Online (Sandbox Code Playgroud)
要重现,并假设您有本地sql server 2008 R2实例,请将以下代码粘贴到linqpad中并将其作为程序运行.
它爆炸了:
链接服务器'(null)'的OLE DB提供程序'STREAM'返回列'[!BulkInsert] .Value'的无效数据.
void Main()
{
SqlConnection cn = new SqlConnection("data source=localhost;Integrated Security=SSPI;initial catalog=tempdb;Connect Timeout=180;");
cn.Open();
IList<decimal> list = new List<decimal>() {-8m, 8m};
decimal result = list.Sum(x => x);
Console.WriteLine(result == 0);
string tableName …Run Code Online (Sandbox Code Playgroud) 最快的方法是:
我现在应该做什么:
我每秒输入大约60k-75k行,这还不够,但非常接近.我想要达到250.000行.
到目前为止还没有真正使用过.我得到20%的时间"网络I/O"块,有一个核心80%加载CPU端.光盘写出7mb-14mb,大部分是空闲的.RAID 10上的6个raptors的平均队列长度是...... 0.25.
任何人都知道如何加快速度?更快的服务器(到目前为止它是虚拟的,8GB RAM,4个核心,物理磁盘通过数据).
添加一些说明:
垂直分区是否有助于,例如通过一个字节(tinyint)将仪器世界分开,例如16个表格,因此我最多同时进行16次插入?实际上,数据来自不同的交易所,我可以为每个交易所制作一个分区.这将是一个自然的分裂场(实际上是在乐器中,但我可以在这里复制这些数据).
更多澄清:速度更高(90k),现在明显受到机器之间的网络IO的限制,这可能是VM切换.
我现在要做的就是做每32K行的连接,搭起一个临时表,插入此与SqlBUlkdCopy,然后用一条SQL语句复制到主表 - 在主表最大限度地减少任何锁定时间.
大多数等待时间现在仍在网络IO上.似乎我遇到了VM明智的问题.将在未来几个月转移到物理硬件;)
sqlbulkcopy ×10
c# ×7
sql-server ×4
bulkinsert ×3
ado.net ×2
sql ×2
.net ×1
c#-4.0 ×1
database ×1
datetime ×1
performance ×1