ConvertTo- Json в объекте с массивом в качестве значения свойства - PullRequest
1 голос
/ 26 марта 2020

В Windows Powershell У меня есть простой запрос Invoke-SqlCmd, который возвращает следующую таблицу:

ID Text
-- ----
 1 FOO 
 2 BAR 
 3 SPAM

Передача в | ConvertTo-Json -Depth 1 дает следующий результат:

[
    {
        "RowError":  "",
        "RowState":  1,
        "Table":  "",
        "ItemArray":  "1 FOO",
        "HasErrors":  false,
        "ID":  1,
        "Text":  "FOO"
    },
    {
        "RowError":  "",
        "RowState":  1,
        "Table":  "",
        "ItemArray":  "2 BAR",
        "HasErrors":  false,
        "ID":  2,
        "Text":  "BAR"
    },
    {
        "RowError":  "",
        "RowState":  1,
        "Table":  "",
        "ItemArray":  "3 SPAM",
        "HasErrors":  false,
        "ID":  3,
        "Text":  "SPAM"
    }
]

Моим желаемым выводом будет не этот пустой массив, а объект с одним свойством , имеющим "Products" в качестве имени и массив в качестве значения.

Кроме того, Я хотел бы, чтобы мои записи массива были объектами, имеющими только столбцы таблицы SQL в качестве свойств.

То есть, мой желаемый результат будет:

{
    "Products": [
        {
            "ID": 1,
            "Text": "FOO"
        },
        {
            "ID": 2,
            "Text": "BAR"
        },
        {
            "ID": 3,
            "Text": "SPAM"
        }
    ]
}

Как мне добиться это?


РЕДАКТИРОВАТЬ: запрос и его результат от SQL Server Management Studio следующие: Query and result in SSMS

1 Ответ

3 голосов
/ 26 марта 2020

Предполагается, что $queryResult содержит результат вашего Invoke-SqlCmd вызова:

[pscustomobject] @{ 
  Products = @($queryResult | Select-Object ID, Text)
} | ConvertTo-Json
  • Select-Object создает [pscustomobject] экземпляров, которые содержат свойства представляющие только столбцы фактической таблицы, жестко закодированные в этом случае.

    • Примечание. Определение имен этих столбцов динамически дает более общее решение c - см. следующий раздел.
  • @(), оператор подвыражения массива , гарантирует, что результат будет обработан как массив (в случае, если ваш запрос возвращает просто one row).

  • [pscustomobject] @{ ... } - это syntacti c сахар для создания экземпляра оболочки [pscustomobject], единственное свойство которого, Products, содержит массив объекты только для значений столбцов.

  • ConvertTo-Json преобразует полученный пользовательский объект обратно в JSON.

    • Хотя здесь это не проблема, обратите внимание что глубина рекурсии ограничена 2 по умолчанию, что требует явного использования -Depth для предотвращения потери данных - см. этот пост .

Определение имен столбцов динамически:

Матиас Р. Йессен , при поддержке Фрай Симпсон , разработал это решение.

Сделав вызов Invoke-SqlCmd, верните System.Data.Table экземпляр
via -OutputAs DataTables, .Column.ColumnNames может использоваться для извлечения имен столбцов запроса в виде массива:

# Note the use of `-OutputAs DataTables`; `-As DataTables` should work too.
$queryResult = Invoke-SqlCmd -OutputAs DataTables -Query "SELECT * FROM Schema1.dbo.Table_1" -ServerInstance $instanceName -Database $databaseName  

[pscustomobject] @{ 
  Products = @($queryResult | Select-Object $queryResult.Columns.ColumnName) 
} | ConvertTo-Json 

По умолчанию Invovke-SqlCmd возвращает поток отдельных System.Data.DataRow экземпляров.

Обратите внимание, как, даже если $queryResult содержит экземпляр System.Data.DataTable, его строк неявно отправляются через конвейер; другими словами: $queryResult | ... - это то же самое, что и $queryResult.Rows | ..., поведение, встроенное в PowerShell.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...