sql >> Database teknologi >  >> RDS >> Sqlserver

VÆLG FOR XML AUTO og returner datatyper

FOR XML blev introduceret i SQL Server 2000.

SQL Server 2000 havde ikke MAX datatyper eller XML datatype. Det var heller ikke muligt at bruge FOR XML i en underforespørgsel.

Artiklen Hvad returnerer server side FOR XML? forklarer

I SQL Server 2000 ... FOR XML ... blev implementeret i kodelaget mellem forespørgselsprocessoren og datatransportlaget ... forespørgselsprocessoren producerer resultatet på samme måde som uden FOR XML og derefter FOR XML kode formaterer rækkesættet som XML. For maksimal XML-udgivelsesydelse FOR XML udfører dampende XML-formatering af det resulterende rækkesæt og sender dets output direkte til serversidens TDS-kode i små bidder uden at bufre hele XML i serverrummet. Klumpstørrelsen er 2033 UCS-2-tegn. Således sendes XML større end 2033UCS-2 tegn til klientsiden i flere rækker, der hver indeholder en del af XML. SQL Server bruger et foruddefineret kolonnenavn for dette rækkesæt med én kolonne af typen NTEXT -“XML_F52E2B61-18A1-11d1-B105-00805F49916B ” – for at angive chunked XMLrowset i UTF-16-kodning.

Så det ser ud til, at dette stadig er implementeret på samme måde for topniveau FOR XML også i senere versioner.

SQL Server 2005 introducerede muligheden for at bruge FOR XML i underforespørgsler (hvilket betyder, at disse nu skal håndteres af forespørgselsprocessoren i stedet for et lag uden for den, mens resultaterne streames til klienten)

Den samme artikel forklarer, at disse vil blive skrevet som NVARCHAR(MAX) eller XML afhængig af tilstedeværelsen eller ej af en type direktiv.

Ud over datatypeforskellen betyder dette den ekstra SELECT wrapper kan gøre en drastisk forskel i ydeevne, hvis #tab er stor.

/*Can be streamed straight out to client without using server storage*/
SELECT col
FROM #tab
FOR XML AUTO

/*XML constructed in its entirety in tempdb first*/
SELECT(SELECT col
FROM #tab
FOR XML AUTO) AS wrapped_subquery

Det er muligt at se de forskellige tilgange i opkaldsstakkene samt udførelsesplaner.

Direkte streamet

sqllang.dll!CXMLExecContext::AddTagAndAttributes()  + 0x5a9 bytes                   
sqllang.dll!CXMLExecContext::AddXMLRow()  + 0x2b7 bytes                 
sqltses.dll!CEsExec::FastMoveEval()  + 0x9c bytes                   
sqllang.dll!CXStmtQuery::ErsqExecuteQuery()  + 0x280 bytes                  
sqllang.dll!CXStmtXMLSelect::WrapExecute()  + 0x2d7 bytes                   
sqllang.dll!CXStmtXMLSelect::XretDoExecute()  + 0x355 bytes                 
sqllang.dll!CXStmtXMLSelect::XretExecute()  + 0x46 bytes                    
sqllang.dll!CMsqlExecContext::ExecuteStmts<1,1>()  + 0x368 bytes                    
sqllang.dll!CMsqlExecContext::FExecute()  + 0x6cb bytes                 
sqllang.dll!CSQLSource::Execute()  + 0x3ee bytes                    
sqllang.dll!process_request()  + 0x757 bytes    

Med underforespørgsel

sqllang.dll!CXMLExecContext::AddTagAndAttributes()  + 0x5a9 bytes
sqllang.dll!CXMLExecContext::AddXMLRow()  + 0x2b7 bytes
sqllang.dll!CForXmlSerialize::ProcessRow()  + 0x19 bytes
sqllang.dll!CUDXR_Base::PushRow()  + 0x30 bytes
sqlmin.dll!CQScanUdx::Open()  + 0xd5 bytes
sqlmin.dll!CQueryScan::StartupQuery()  + 0x170 bytes
sqllang.dll!CXStmtQuery::SetupQueryScanAndExpression()  + 0x391 bytes
sqllang.dll!CXStmtQuery::InitForExecute()  + 0x34 bytes
sqllang.dll!CXStmtQuery::ErsqExecuteQuery()  + 0x217 bytes
sqllang.dll!CXStmtSelect::XretExecute()  + 0xed bytes
sqllang.dll!CMsqlExecContext::ExecuteStmts<1,1>()  + 0x368 bytes
sqllang.dll!CMsqlExecContext::FExecute()  + 0x6cb bytes
sqllang.dll!CSQLSource::Execute()  + 0x3ee bytes
sqllang.dll!process_request()  + 0x757 bytes

Begge ender med at kalde den samme underliggende XML-kode, men den "uindpakkede" version har ingen XML-iteratorer i selve planen, resultatet opnås ved at erstatte metodekald fra CXStmtSelect med CXStmtXMLSelect i stedet (repræsenteret i planen som en XML Select-rodknude i stedet for en almindelig gammel Select).

På SQL Server 2016 CTP3 ser jeg stadig ntext for topniveau FOR XML . Dog øverste niveau FOR JSON vises som nvarchar(max)

I det mindste i CTP'en indeholder JSON-specialkolonnenavnet stadig GUID'et F52E2B61-18A1-11d1-B105-00805F49916B på trods af, at oprindelsen til dette er IXMLDocument Interface.

Planerne ser meget ens ud, selvom XML Select er erstattet med en JSON Select

BTW:På build Microsoft SQL Server 2014 - 12.0.4213.0 (X64) Jeg kan ikke se nogen forskel i adfærd mellem vikarborde og permanente borde. Dette skyldes sandsynligvis den forskellige @@Version mellem miljøerne bruger dit spørgsmål http://sqlfiddle.com/ (12.0.2000.8) og https://data.stackexchange.com/ (12.0.4213.0).

Måske er en fejl rettet i sys.dm_exec_describe_first_result_set mellem de to 2014-bygninger.

I 2012 får jeg de samme resultater som Shnugo den 11.0.5343.0 (med NULL i de første tre rækker), men efter installation af SP3 11.0.6020.0 får jeg det samme som dine første resultater vist i spørgsmålet.



  1. SSIS-opgave til import af inkonsistent kolonneantal?

  2. Postgresql-tabeller eksisterer, men hentning af relation eksisterer ikke, når der forespørges

  3. Hvordan ATAN2() virker i MariaDB

  4. Er det muligt at bruge retur i lagret procedure?