1

假设我有一个包含以下列的 SQL 表:

[server_name],[SESSION_ID],[SESSION_SPID]

我正在尝试将存储在数据表 ( $dmvResult) 中的值复制到上面的 SQL 表 ( $Table)

$dmvResult = DMV_Query 'SELECT [SESSION_ID]
      ,[SESSION_SPID]
FROM $SYSTEM.DISCOVER_SESSIONS';

$ConnectionString ='Data Source=$server; Database=$database; Trusted_Connection=True;'
$bulkCopy = new-object Data.SqlClient.SqlBulkCopy($ConnectionString)
$bulkCopy.DestinationTableName=$Table
$bulkCopy.WriteToServer($dmvResult)

虽然复制成功完成,但存在一个问题:它是按位置复制,而不是按列名匹配。换句话说,复制的列没有被映射并复制到相同的列。

[SESSION_ID] 被复制到 [server_name] 并且 [SESSION_SPID] 被复制到 [SESSION_ID]

如何告诉 bulkCopy 匹配列并复制?

结果副本应该是 [server_name] 为空,因为它不是从 DMV 查询中选择的。

我在这个线程中找到了一个巧妙的解决方案:

https://stackoverflow.com/a/20045505/8397835

但我不知道如何将其转换为我的 powershell 代码:

var meta = definition.Context.Mapping.GetMetaType(typeof(T));
        foreach (var col in meta.DataMembers)
        {
            copy.ColumnMappings.Add(col.Member.Name, col.MappedName);
        }

编辑:foreach column.ColumnName 输出 foreach输出

EDIT2:我试过这个:

$dmvResult.Columns |%{$_.Name}

它不输出任何东西。

在您说 $dmvResult 数据表必须为空之前,请解释一下这实际上如何工作并复制数据?

$bulkCopy.ColumnMappings.Add('SESSION_ID', 'SESSION_ID')
$bulkCopy.ColumnMappings.Add('SESSION_SPID', 'SESSION_SPID')
$bulkCopy.WriteToServer($dmvResult)

由于某种原因,它也将其输出到控制台:

控制台输出

所以数据表 $dmvResult 被清楚地填充了。

我希望而不是像这样为每一列定义映射:

$bulkCopy.ColumnMappings.Add('SESSION_SPID', 'SESSION_SPID')

相反,会有这样的自动选项:

foreach ($column in $dmvResult.Columns) { $bulkCopy.ColumnMappings.Add($column.ColumnName, $column.ColumnName)}

但这会引发异常:

使用“1”参数调用“WriteToServer”的异常:“给定的 ColumnMapping 与源或目标中的任何列都不匹配。”

4

1 回答 1

1

一个非常奇怪的解决方案,但我之前只需要在这里添加一个逗号$dataset

,$dataSet.Tables[0]

在 DMV_Query 函数中

然后我使用了这个 foreach 循环

foreach ($column in $dmvResult.Columns) { $bulkCopy.ColumnMappings.Add($column.ColumnName, $column.ColumnName) > $null }

它奏效了!

它现在自动映射列!

于 2019-02-01T01:11:41.043 回答