1

我正在尝试使用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
            }
        }
    }
},
.
.
.

虽然column_id现在是我想要的位置,但columns现在是唯一正确嵌套的东西。table现在每个都针对它的每个重复,并且每个都针对它的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
                }
            ]
        }
    ]
},
.
.
.

嵌套选择末尾的andAS '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')

用 JSON 替换 XML。

于 2015-12-28T01:36:48.353 回答