【问题标题】:ConvertTo-Json in object with array as property value以数组为属性值的对象中的 ConvertTo-Json
【发布时间】:2020-07-07 01:27:21
【问题描述】:

在 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"
    }
]

我想要的输出不是这个裸数组,而是一个 object,它有一个 property,名称为“Products”,数组为值。

此外,我希望我的数组条目是仅将 SQL 表的列作为属性的对象。

也就是说,我想要的输出是:

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

我怎样才能实现它?


编辑:SQL Server Management Studio 的查询及其结果如下:

【问题讨论】:

    标签: json sql-server powershell convertto-json


    【解决方案1】:

    假设$queryResult 包含您的Invoke-SqlCmd 调用的结果:

    [pscustomobject] @{ 
      Products = @($queryResult | Select-Object ID, Text)
    } | ConvertTo-Json
    
    • Select-Object 创建 [pscustomobject] 实例,其中包含仅表示实际表列的属性,在这种情况下是硬编码的。

      • 注意:动态地确定这些列名可以提供更通用的解决方案 - 请参阅下一节。
    • @()array-subexpression operator,确保结果被视为一个数组(以防您的查询恰好返回 一个 行)。

      李>
    • [pscustomobject] @{ ... } 是用于创建包装器 [pscustomobject] 实例的语法糖,其唯一属性 Products 包含仅列值对象的数组。

    • ConvertTo-Json 将生成的自定义对象转换回 JSON。

      • 虽然这不是问题,但请注意递归深度默认限制为 2,需要显式使用 -Depth 以防止数据丢失 - 请参阅 this post

    动态确定列名:

    Mathias R. JessenFry Simpson 的协助下制定了这个解决方案。

    通过使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 中内置的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-01
      • 2021-11-30
      • 2019-03-27
      • 1970-01-01
      • 2021-11-19
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多