bigxml4u
Alguns planos de consulta são muito grandes para serem armazenados adequadamente como XML. Você recebe o erro:XML datatype instance has too many levels of nested nodes. Maximum allowed depth is 128 levels.
O que está bem. Tudo precisa de limitações para evitar o uso indevido. Quem sabe o que aconteceria em 129 níveis aninhados.
Obviamente, com planos de consulta, você pode salvar o XML do formato de texto como um arquivo .sqlplan e reabri-lo como um plano de execução gráfico.
O problema que estou tendo com minha consulta é que quando tento exibir isso, <
é alterado para <
e >
para >
. Isso adiciona duas etapas extras antes que você possa salvar o arquivo como um .sqlplan válido, que pode ser reaberto.
No momento, minha consulta faz o seguinte:
query_plan =
CASE
WHEN TRY_CAST(qsp.query_plan AS XML) IS NOT NULL
THEN TRY_CAST(qsp.query_plan AS XML)
WHEN TRY_CAST(qsp.query_plan AS XML) IS NULL
THEN
(
SELECT
(
SELECT
N''-- '' + NCHAR(13) + NCHAR(10) +
N''-- This is a huge query plan.'' + NCHAR(13) + NCHAR(10) +
N''-- Remove the headers and footers, save it as a .sqlplan file, and re-open it.'' + NCHAR(13) + NCHAR(10) +
N''-- Depending on local factors, you may need to replace "<" and ">" too.'' + NCHAR(13) + NCHAR(10) +
N''-- '' + NCHAR(13) + NCHAR(10) +
REPLACE(qsp.query_plan, N''<RelOp'', NCHAR(13) + NCHAR(10) + N''<RelOp'') +
NCHAR(13) + NCHAR(10) + N''--'' COLLATE Latin1_General_Bin2 AS [processing-instruction(query_plan)]
)
FOR XML PATH(N''''),
TYPE
)
END,
Normalmente, eu seguiria meu próprio conselho e adicionaria isso ao final, mas isso me traz de volta ao erro XML original sobre nós e aninhamento e 128, etc.
.value
(
'./text()[1]',
'nvarchar(max)'
);
Tentei adicionar REPLACE
seleções internas e externas para tentar consertar as coisas, mas o blob parece imune aos meus encantos.
Existe uma maneira de impedir ou contornar a conversão desses caracteres para facilitar um pouco mais o salvamento do arquivo?
Se você tiver uma cópia do banco de dados StackOverflow localmente, poderá gerar um plano de consulta que termina nulo em TRY_CAST
e gera um erro quando tratado como XML com esta consulta:
WITH
p0 AS (SELECT pt.* FROM dbo.PostTypes AS pt),
p1 AS (SELECT pp.* FROM p0 AS p CROSS JOIN p0 AS pp),
p2 AS (SELECT pp.* FROM p1 AS p CROSS JOIN p1 AS pp),
p3 AS (SELECT pp.* FROM p2 AS p CROSS JOIN p2 AS pp),
p4 AS (SELECT pp.* FROM p3 AS p CROSS JOIN p3 AS pp),
p5 AS (SELECT pp.* FROM p4 AS p CROSS JOIN p4 AS pp),
p6 AS (SELECT pp.* FROM p5 AS p CROSS JOIN p5 AS pp),
p7 AS (SELECT pp.* FROM p6 AS p CROSS JOIN p6 AS pp),
p8 AS (SELECT pp.* FROM p7 AS p CROSS JOIN p7 AS pp),
p9 AS (SELECT pp.* FROM p8 AS p CROSS JOIN p8 AS pp)
SELECT
c = COUNT_BIG(*)
FROM p9 AS p
OPTION(RECOMPILE);
Se você quiser apenas ver o absurdo gerado, você pode usar este link principal do GitHub .
Você está selecionando muitos níveis na parte problemática do seu código.
Sua versão simplificada
Resultado
Em vez disso, tente fazer isso
for xml path
diretamente na consulta de instrução de processamentoResultado
Explicação:
select '<>' as [processing-instruction(query_plan)]
por si só não faz nada além de retornar o valor da string com algum nome de coluna de aparência estranha.É quando você adiciona
for xml path
que a mágica acontece e a instrução de processamento passa a fazer parte do xml.A consulta
select (select '<>' as [processing-instruction(query_plan)])
retornará o valor da string sem o nome sofisticado da coluna e por issofor xml path
não cria uma instrução de processamento para você. Em vez disso, é apenas uma string que é autorizada como deveria ser para XML válido.