我有一个dataTable,我将把它用于BulkCopy到目标表。 我正在尝试解决主键违规问题。因此,我没有使用临时表,而是与生产合并,而是尝试从内存中的DataTable中删除冗余行,然后再将其传递给WriteToServer方法。
在我的代码中,我根据列和字段以与数据库中的表格相同的格式创建了Memory DataTable列。所以我没有做任何列映射。 我的PK记录是具有唯一值约束的GUID,称为PKID。我从磁盘上的CSV文件填充DataTable,然后执行BulkCopy。
我的想法是尝试执行以下逻辑: 从PKID所在的MemoryDataTable中删除(来自SQLTable的SELECT PKID)
这是我的代码:
Try
Using sqlBulk As New SqlBulkCopy(LocalDBConnectionString, SqlBulkCopyOptions.TableLock)
sqlBulk.DestinationTableName = "DataRecords"
sqlBulk.BatchSize = 5000
sqlBulk.WriteToServer(MemoryDataTable)
sqlBulk.Close()
End Using
Catch ex As Exception
EventArgs.ErrorMessage = ex.Message
''''Catch Primary Key Violation Here''''
End Try
答案 0 :(得分:0)
您无法执行此操作,因为MemoryDataTable仅存在于您的vb.net程序的上下文中,即SQL / Server对此一无所知。
但是,您可以将内存表加载到服务器上的临时表中,然后在其上执行您喜欢的任何SQL操作。 E.g。
Select * into #TempDataTable From SQLTable
然后将您的SqlBulk加载到#TempDataTable中,并且1)将#TempDataTable合并到SQLTable中或执行插入/删除操作。注意# - 这使得该表成为临时表,如果您在使用它之后不丢弃它,它将自动清除。但是,完成它们后删除临时表是个好习惯。
我真的建议您使用MERGE语句,它比删除和插入更有效。
答案 1 :(得分:0)
谢谢,这可能是个不错的选择。 但是,我确实完成了我想做的事:) 在catch部分,我从实时DB表中选择了所有PK到DataReader中。然后我循环读取返回的行。在每个循环中,我使用MemoryDataTable.rows.find方法检查MemoryDataTable中是否存在DataReader行,如果是,我将其删除。