我正在尝试使用FOR JSON PATH
更改查询的JSON输出嵌套。 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 PATH
我想要的位置(如FOR JSON AUTO
查询的输出)(如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')
查询的输出)吗
更新 - 工作
根据DimaSUN的回复和Ben的评论,我想出了这个现在正在运行的查询:
.
.
.
{
"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
}
]
}
]
},
.
.
.
新查询输出(摘要):
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.
是关键部分,否则我收到以下错误:
Number.MAX_SAFE_INTEGER
答案 0 :(得分: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。