#powershell
#powershell
Вопрос:
У меня есть два запроса, выполняемых в разных экземплярах SQL. Я должен выполнить их как два отдельных запроса.
Мне нужно объединить результаты из них в один, чтобы я мог создать CSV-файл со всеми строками из $result, когда есть совпадение в $lookup . Сопоставление выполняется путем сравнения столбцов с именем ID в обоих.
Файл CSV должен содержать все столбцы из $result, а также все столбцы из соответствующей строки в $lookup, за исключением ID .
Имена столбцов неизвестны, за исключением идентификатора, который есть в обоих.
Для создания CSV я планирую использовать Export-CSV. Но мне нужно как-то объединить два результата.
$result = @(Invoke-Sqlcmd –ServerInstance $ServerInstance –Database $Database -ErrorVariable sqlerr -OutputSqlErrors $true -Query $sql -QueryTimeout 0 -ErrorAction Stop | select *)
$lookup = @(Invoke-Sqlcmd –ServerInstance $ServerInstance –Database $Database -ErrorVariable sqlerr -OutputSqlErrors $true -Query $sql -QueryTimeout 0 -ErrorAction Stop | select *)
Я пробовал, например, это:
($result | select *) | Join ($lookup | select *) -on ID -eq ID
РЕДАКТИРОВАТЬ: получилось, ответьте ниже.
Комментарии:
1. Рассматривали ли вы возможность использования связанных серверов? Затем вы можете объединить оба набора данных в 1 запрос.
2. Да, но это не вариант.
Ответ №1:
Я предлагаю что-то в этом роде:
- перечислить столбцы
$result
и$lookup
- определите столбцы для добавления
- расширить
$result
с помощью этих столбцов - перебирать строки
$result
, чтобы получить совпадающую строку$lookup
- вставить значения
Непроверенный сценарий:
## the following commands are incomplete (missing closing parenthesis)
# $result = @(Invoke-Sqlcmd –ServerInstance $ServerInstance –Database $Database -ErrorVariable sqlerr -OutputSqlErrors $true -Query $sql -QueryTimeout 0 -ErrorAction Stop | select *
# $lookup = @(Invoke-Sqlcmd –ServerInstance $ServerInstance –Database $Database -ErrorVariable sqlerr -OutputSqlErrors $true -Query $sql -QueryTimeout 0 -ErrorAction Stop | select *
$resultCols = $result.PsObject.Properties.Name
$AppendCols = $lookup.PsObject.Properties.Name | Where Name -notin $resultCols
$result = $result | Select-Object -Property *,$AppendCols
foreach($Row in $result){
$lookupID = $lookup | Where-Object ID -eq $Row.ID
if($lookupID){
foreach($Col in $AppendCols){
$Row.$Col = $lookupID.$Col
}
}
}
$result | Export-Csv -NoTypeInformation .ExtendedResult.csv
Комментарии:
1. Спасибо, но я получаю сообщение об ошибке от «$Row [$ Col] = $ lookupID [$ Col]»: невозможно выполнить индексацию в объект типа System.Management. Автоматизация. PSObject.
2. Пожалуйста, попробуйте
$Row.$Col = $lookupID.$Col
вместо3. Какой тип, содержимое
$resultCols
,$lookupCols
есть?4. У меня нет под рукой sql-сервера для детализации
$result|Get-Member
, чтобы узнать, какие свойства доступны5. Чтобы быть полезным для будущих читателей, не стесняйтесь редактировать мой ответ или представить свой собственный.
Ответ №2:
Я переключился на использование «System.Data.SqlClient» при извлечении данных. Затем приведенный ниже код сработал. Спасибо, LotPings, что указали мне правильное направление.
$resultCols = ($result.Columns | ForEach-Object {$_.ColumnName})
$AppendCols = ($lookup.Columns | ForEach-Object {$_.ColumnName})
$AppendCols = $AppendCols | Where-Object {$_ -ne 'ID'}
$AllCols = $resultCols $AppendCols
$result = $result | Select-Object -Property $AllCols
$output = @()
foreach($Row in $result)
{
$lookupIDRow = $lookup | Where-Object ID -eq $Row.ID
if($lookupIDRow)
{
foreach($Col in $AppendCols)
{
$Row.$Col = $lookupIDRow.$Col
}
$output =$Row
}
}
Комментарии:
1.
$Output
будет содержать только объединенные строки, предназначено ли это? В противном случае строки без сопоставленияID
в$lookup
будут иметь значение $null в качестве значения в добавленных столбцах.2. Да, должны выводиться только совпадающие строки. Я еще не проверил эту часть, но это требование.