1

を使用して、クエリからの JSON 出力のネストを変更しようとしていますFOR JSON PATH。クエリはほとんど必要なものですが、完全ではFOR JSON AUTOありません。

を使用してクエリFOR JSON AUTO:

SELECT 
    table_name      = tables.name,
    table_object_id = tables.object_id,
    index_name      = indexes.name,
    index_id        = indexes.index_id,
    column_name     = columns.name,
    column_id       = index_columns.index_column_id,
    max_length      = columns.max_length,
    precision       = columns.precision,
    scale           = columns.scale

FROM 
     sys.indexes        indexes 
INNER JOIN 
     sys.index_columns  index_columns  ON  indexes.object_id = index_columns.object_id and indexes.index_id = index_columns.index_id 
INNER JOIN 
    sys.columns         columns        ON  index_columns.object_id = columns.object_id and index_columns.column_id = columns.column_id 
INNER JOIN 
    sys.tables          tables         ON  indexes.object_id = tables.object_id 

WHERE tables.name LIKE 'tbl_%'

ORDER BY 
    tables.name, indexes.index_id, index_columns.index_column_id

FOR JSON AUTO

出力を使用したクエリFOR JSON AUTO(スニペット):

.
.
.
{
    "table_name": "tbl_Agent",
    "table_object_id": 176055713,
    "indexes": [
        {
            "index_name": "PK_Task_tbl_Agent",
            "index_id": 1,
            "columns": [
                {
                    "column_name": "PartitionId",
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0,
                    "index_columns": [
                        {
                            "column_id": 1
                        }
                    ]
                },
                {
                    "column_name": "AgentId",
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0,
                    "index_columns": [
                        {
                            "column_id": 2
                        }
                    ]
                }
            ]
        },
        {
            "index_name": "IX_Task_tbl_Agent_PoolId_AgentName",
            "index_id": 2,
            "columns": [
                {
                    "column_name": "PartitionId",
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0,
                    "index_columns": [
                        {
                            "column_id": 1
                        }
                    ]
                },
                {
                    "column_name": "PoolId",
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0,
                    "index_columns": [
                        {
                            "column_id": 2
                        }
                    ]
                },
                {
                    "column_name": "AgentName",
                    "max_length": 128,
                    "precision": 0,
                    "scale": 0,
                    "index_columns": [
                        {
                            "column_id": 3
                        }
                    ]
                }
            ]
        },
        {
            "index_name": "IX_Task_tbl_Agent_PoolId_SessionId",
            "index_id": 3,
            "columns": [
                {
                    "column_name": "PartitionId",
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0,
                    "index_columns": [
                        {
                            "column_id": 1
                        }
                    ]
                },
                {
                    "column_name": "PoolId",
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0,
                    "index_columns": [
                        {
                            "column_id": 2
                        }
                    ]
                },
                {
                    "column_name": "SessionId",
                    "max_length": 16,
                    "precision": 0,
                    "scale": 0,
                    "index_columns": [
                        {
                            "column_id": 3
                        }
                    ]
                }
            ]
        }
    ]
},
.
.
.

各テーブルには適切にネストされたすべてのインデックスがあり、各インデックス内では、インデックスのすべての列 (これらは複合インデックス) が適切にネストされています。私が加えたい唯一の変更は、ネストを解除しindex_columnsて、column_idの一部にすることですcolumns

.
.
.
"columns": [
    {
        "column_name": "PartitionId",
        "max_length": 4,
        "precision": 10,
        "scale": 0,
  --->  "column_id": 1
    },
    {
        "column_name": "PoolId",
        "max_length": 4,
        "precision": 10,
        "scale": 0,
  --->  "column_id": 2
    },
    {
        "column_name": "AgentName",
        "max_length": 128,
        "precision": 0,
        "scale": 0,
  --->  "column_id": 3
    }
]
.
.
.

ただし、を使用しようとするとFOR JSON PATH、不適切にネストされてしまいます。

を使用してクエリFOR JSON PATH:

SELECT 

    tables.name                   AS [tables.table_name],
    tables.object_id              AS [tables.table_object_id],
    indexes.name                  AS [tables.indexes.index_name],
    indexes.index_id              AS [tables.indexes.index_id],
    columns.name                  AS [tables.indexes.columns.column_name],
    index_columns.index_column_id AS [tables.indexes.columns.column_id],
    columns.max_length            AS [tables.indexes.columns.max_length],
    columns.precision             AS [tables.indexes.columns.precision],
    columns.scale                 AS [tables.indexes.columns.scale]

FROM 
     sys.indexes        indexes 
INNER JOIN 
     sys.index_columns  index_columns  ON  indexes.object_id = index_columns.object_id and indexes.index_id = index_columns.index_id 
INNER JOIN 
     sys.columns        columns        ON  index_columns.object_id = columns.object_id and index_columns.column_id = columns.column_id 
INNER JOIN 
     sys.tables         tables         ON  indexes.object_id = tables.object_id 

WHERE tables.name LIKE 'tbl_%'

ORDER BY 
     tables.name, indexes.index_id, index_columns.index_column_id

FOR JSON PATH

出力を使用したクエリFOR JSON PATH(スニペット):

.
.
.
{
    "tables": {
===>    "table_name": "tbl_Agent",
        "table_object_id": 176055713,
        "indexes": {
  --->      "index_name": "PK_Task_tbl_Agent",
            "index_id": 1,
            "columns": {
                "column_name": "PartitionId",
                "column_id": 1,
                "max_length": 4,
                "precision": 10,
                "scale": 0
            }
        }
    }
},
{
    "tables": {
===>    "table_name": "tbl_Agent",
        "table_object_id": 176055713,
        "indexes": {
  --->      "index_name": "PK_Task_tbl_Agent",
            "index_id": 1,
            "columns": {
                "column_name": "AgentId",
                "column_id": 2,
                "max_length": 4,
                "precision": 10,
                "scale": 0
            }
        }
    }
},
{
    "tables": {
===>    "table_name": "tbl_Agent",
        "table_object_id": 176055713,
        "indexes": {
            "index_name": "IX_Task_tbl_Agent_PoolId_AgentName",
            "index_id": 2,
            "columns": {
                "column_name": "PartitionId",
                "column_id": 1,
                "max_length": 4,
                "precision": 10,
                "scale": 0
            }
        }
    }
},
.
.
.

whilecolumn_idは私が望んでいる場所ですが、columns適切にネストされているのは だけです。eachtableはその ごとに繰り返され、 each はそのindexesごとindexに繰り返されますcolumns

適切なネスト (クエリからの出力など) を維持しながら、必要な場所 (クエリcolumn_idからの出力など)を取得するにはどうすればよいですか?FOR JSON PATHFOR JSON AUTO

更新 -- 動作中

DimaSUN の応答と Ben のコメントに基づいて、現在機能している次のクエリを思いつきました。

SELECT 
    tables.name      AS [table_name],
    tables.object_id AS [table_object_id],

   (SELECT 
        indexes.name     AS [index_name],
        indexes.index_id AS [index_id],

       (SELECT
            columns.name                  AS [column_name],
            index_columns.index_column_id AS [column_id],
            columns.max_length            AS [max_length],
            columns.precision             AS [precision],
            columns.scale                 AS [scale]
            FROM 
                sys.index_columns index_columns
                JOIN
                sys.columns columns ON index_columns.object_id = columns.object_id and index_columns.column_id = columns.column_id 
            WHERE
                indexes.object_id = index_columns.object_id and indexes.index_id = index_columns.index_id
            ORDER BY
                index_columns.index_column_id
            FOR JSON PATH
       ) AS 'columns'

    FROM
        sys.indexes indexes
    WHERE 
        indexes.object_id = tables.object_id
    ORDER BY
        indexes.index_id
    FOR JSON PATH
    ) AS 'indexes'

FROM
    sys.tables tables
WHERE
    tables.name LIKE 'tbl_%'
ORDER BY
    tables.name
FOR JSON PATH, ROOT('tables')

新しいクエリ出力 (スニペット):

.
.
.
{
    "table_name": "tbl_Agent",
    "table_object_id": 176055713,
    "indexes": [
        {
            "index_name": "PK_Task_tbl_Agent",
            "index_id": 1,
            "columns": [
                {
                    "column_name": "PartitionId",
                    "column_id": 1,
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0
                },
                {
                    "column_name": "AgentId",
                    "column_id": 2,
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0
                }
            ]
        },
        {
            "index_name": "IX_Task_tbl_Agent_PoolId_AgentName",
            "index_id": 2,
            "columns": [
                {
                    "column_name": "PartitionId",
                    "column_id": 1,
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0
                },
                {
                    "column_name": "PoolId",
                    "column_id": 2,
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0
                },
                {
                    "column_name": "AgentName",
                    "column_id": 3,
                    "max_length": 128,
                    "precision": 0,
                    "scale": 0
                }
            ]
        },
        {
            "index_name": "IX_Task_tbl_Agent_PoolId_SessionId",
            "index_id": 3,
            "columns": [
                {
                    "column_name": "PartitionId",
                    "column_id": 1,
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0
                },
                {
                    "column_name": "PoolId",
                    "column_id": 2,
                    "max_length": 4,
                    "precision": 10,
                    "scale": 0
                },
                {
                    "column_name": "SessionId",
                    "column_id": 3,
                    "max_length": 16,
                    "precision": 0,
                    "scale": 0
                }
            ]
        }
    ]
},
.
.
.

ネストされた選択の最後にある and は重要な部分でした。そうしないと、次のエラーが発生していたからですAS 'columns'AS 'indexes'

Msg 13605, Level 16, State 1, Line 1
Unnamed tables cannot be used as JSON identifiers as well as unnamed columns cannot be used as key names. Add alias to the unnamed column/table.
4

1 に答える 1

1

XMLの場合は次のようになります

  ( select 
    indexes.name                  AS [index_name],
    indexes.index_id              AS [index_id],
    ( select 
    columns.name                  AS [column_name],
    index_columns.index_column_id AS [column_id],
    columns.max_length            AS [max_length],
    columns.precision             AS [precision],
    columns.scale                 AS [scale]
    from 
     sys.index_columns  index_columns 
     JOIN 
     sys.columns        columns        ON  index_columns.object_id = columns.object_id and index_columns.column_id = columns.column_id 
     where    indexes.object_id = index_columns.object_id and indexes.index_id = index_columns.index_id 
     FOR xml PATH(''), root('columns'), type
     )

  from
     sys.indexes        indexes 
     where indexes.object_id = tables.object_id 
     FOR xml PATH(''), root('indices'), type
     )
FROM 
   sys.tables         tables      


WHERE tables.name LIKE 'tbl_%'

--ORDER BY      tables.name, indexes.index_id, index_columns.index_column_id

FOR XML PATH('tables')

XML を JSON に置き換えます。

于 2015-12-28T01:36:48.353 に答える