Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 跳过SqlBulkCopy中的某些列_C#_Sql Server_Sql Server 2008_Sqlbulkcopy_Columnmappings - Fatal编程技术网

C# 跳过SqlBulkCopy中的某些列

C# 跳过SqlBulkCopy中的某些列,c#,sql-server,sql-server-2008,sqlbulkcopy,columnmappings,C#,Sql Server,Sql Server 2008,Sqlbulkcopy,Columnmappings,我正在对两个具有不同列集的SQL Server 2008使用SqlBulkCopy(将一些数据从prod服务器移动到dev)。因此,希望跳过一些尚未存在/尚未删除的列 我该怎么做?使用列映射的一些技巧 编辑: 我下一步要做: DataTable table = new DataTable(); using (var adapter = new SqlDataAdapter(sourceCommand)) { adapter.Fill(table); } table.Columns

我正在对两个具有不同列集的SQL Server 2008使用
SqlBulkCopy
(将一些数据从
prod
服务器移动到
dev
)。因此,希望跳过一些尚未存在/尚未删除的列

我该怎么做?使用
列映射的一些技巧

编辑:

我下一步要做:

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)
DataTable=newdatatable();
使用(var adapter=newsqldataadapter(sourceCommand))
{
适配器。填充(表格);
}
表3.列
第()类
.ForEach(c=>bulk.ColumnMappings.Add(
新的SqlBulkCopyColumnMapping(c.ColumnName,c.ColumnName));
bulk.WriteToServer(表)
并获得:

给定的ColumnMapping与源或目标中的任何列都不匹配

试试这个:


希望您正在寻找相同的

当使用SqlBulkCopyColumnMapping时,只会复制为其创建映射的列

如果不为列创建映射,复制过程将忽略该映射

您可以在演示代码中看到这一点-AdventureWorks演示数据库中的示例源表包含的列多于映射或复制的列

编辑

如果没有关于数据库模式的更多信息,很难确定,但猜测问题在于以下语句:

new SqlBulkCopyColumnMapping(c.ColumnName, c.ColumnName)
根据您的描述,听起来并不是源表中的所有列都存在于目标表中。在
SqlBulkCopyColumnMapping
构造循环中需要一个过滤器来跳过目标中不存在的任何列

我的C#不够好,无法给出一个我相信会奏效的示例,但在伪代码中它会起作用

foreach column c in sourcetable
{
    if c.ColumnName exists in destination_table.columns
    {
          new SqlBulkCopyColumnMapping(c.ColumnName, c.ColumnName)
    }
}
(我确信可以将其转换为lambda表达式)

请注意,在列名匹配但数据类型不兼容的情况下,这并不特别可靠。

DataTable=newdatatable();
使用(var adapter=newsqldataadapter(sourceCommand))
{
适配器。填充(表格);
}
使用(SqlBulkCopy bulk=new SqlBulkCopy(targetConnection,SqlBulkCopyOptions.KeepIdentity,null){DestinationTableName=tableName})
{
foreach(GetMapping中的字符串列名(stringSource、stringTarget、tableName))
{
添加(新的SqlBulkCopyColumnMapping(columnName,columnName));
}
targetConnection.Open();
bulk.WriteToServer(表);
}
私有静态IEnumerable GetMapping(字符串stringSource、字符串stringTarget、字符串tableName)
{
返回可枚举的.Intersect(
GetSchema(stringSource,tableName),
GetSchema(stringTarget,tableName),
StringComparer.Ordinal);//或StringComparer.OrdinalIgnoreCase
}
私有静态IEnumerable GetSchema(字符串连接字符串,字符串表名)
{
使用(SqlConnection连接=新的SqlConnection(connectionString))
使用(SqlCommand=connection.CreateCommand())
{
command.CommandText=“sp_Columns”;
command.CommandType=CommandType.storedProcess;
command.Parameters.Add(“@table_name”,SqlDbType.NVarChar,384),Value=tableName;
connection.Open();
使用(var reader=command.ExecuteReader())
{
while(reader.Read())
{
收益返回(字符串)读取器[“列名称”];
}
}
}
}

埃德·哈珀,这就是没有伪代码的情况 (在这种情况下,从DataTable dt(完全定义)到db中的现有表:

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
{
    bulkCopy.DestinationTableName = "dbo.DepartmentsItems";

    // Write from the source to the destination.
    foreach (DataColumn c in dt.Columns)
    {
        bulkCopy.ColumnMappings.Add(c.ColumnName, c.ColumnName);
    }

    bulkCopy.WriteToServer(dt);
    return dt.Rows.Count;
}

是的,我说的正是这个类。但是如何跳过源代码中的一列?
.Add(newsqldatamapping(“目标上已删除的列”),“”)
?当然,我可以在基础查询中将其从源代码中删除-
选择a、b、c
而不是
选择*
-但这不是一个解决方案如果您不想将其从源代码复制到目标,只需将其从映射中删除。映射将只复制指定列中的数据。请参阅我更新的帖子。我在做什么rong?也许我理解-source有一个列,但target没有。我应该比较source/target模式,只使用中存在的列both@abatishchev-添加了更多详细信息谢谢!您清除了我的视野。但您的示例不适合我,很遗憾,因为我没有目标表,只有它的名称。因此必须调用
sp_列
to确定表列。@abtishchev-很酷而且是可重用的。我相信“stringTarget”和“stringSource”是列名,对吗?@student:嘿,IIRC这些分别是源数据库和目标数据库的连接字符串。太棒了。我需要添加一些代码来正确处理架构和数据库名称,但这正是我需要的。这是一种享受,但值得指出的是,您需要在表上插入权限,因此这可能不起作用,这取决于某些It部门的DB策略:-(horray用于使用sp_列,而不是从表中选择*,其中1=0并从DataReader获取SchemaTable()。您是一个英雄。