Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

PILIH UNTUK XML OTOMATIS dan kembalikan tipe data

FOR XML diperkenalkan di SQL Server 2000.

SQL Server 2000 tidak memiliki MAX tipe data atau XML tipe data. Juga tidak mungkin menggunakan FOR XML dalam subkueri.

Artikel Apa yang dikembalikan sisi server UNTUK XML? menjelaskan

Di SQL Server 2000 ... FOR XML ... diimplementasikan pada lapisan kode antara pemroses kueri dan lapisan pengangkutan data ... pemroses kueri menghasilkan hasil dengan cara yang sama seperti tanpaFOR XML lalu FOR XML kode memformat rowset sebagai XML. Untuk kinerja penerbitan XML maksimum FOR XML tidak mengukus format XML dari rowset yang dihasilkan dan langsung mengirimkan outputnya ke sisi server TDScode dalam potongan kecil tanpa buffering seluruh XML di ruang server. Ukuran potongan adalah 2033 karakter UCS-2. Dengan demikian, XML yang lebih besar dari 2033UCS-2 karakter dikirim ke sisi klien dalam beberapa baris yang masing-masing berisi sepotong XML. SQL Server menggunakan nama kolom yang telah ditentukan sebelumnya untuk baris ini dengan satu kolom jenis NTEXT -“XML_F52E2B61-18A1-11d1-B105-00805F49916B ” – untuk menunjukkan XMLrowset yang dipotong dalam penyandian UTF-16.

Jadi tampaknya ini masih diterapkan dengan cara yang sama untuk FOR XML tingkat atas di versi yang lebih baru juga.

SQL Server 2005 memperkenalkan kemampuan untuk menggunakan FOR XML dalam subkueri (artinya ini sekarang perlu ditangani oleh pemroses kueri alih-alih lapisan di luarnya saat mengalirkan hasilnya ke klien)

Artikel yang sama menjelaskan bahwa ini akan diketik sebagai NVARCHAR(MAX) atau XML tergantung pada ada atau tidaknya type arahan.

Selain perbedaan tipe data, ini berarti tambahan SELECT wrapper dapat membuat perbedaan kinerja yang drastis jika #tab besar.

/*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

Dimungkinkan untuk melihat pendekatan yang berbeda dalam tumpukan panggilan serta rencana eksekusi.

Distreaming langsung

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    

Dengan subkueri

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

Keduanya akhirnya memanggil kode XML dasar yang sama tetapi versi "terbuka" tidak memiliki iterator XML dalam rencana itu sendiri, hasilnya dicapai dengan mengganti panggilan metode dari CXStmtSelect dengan CXStmtXMLSelect sebagai gantinya (diwakili dalam rencana sebagai node root Pilih XML daripada Select lama biasa).

Di SQL Server 2016 CTP3 saya masih melihat ntext untuk FOR XML tingkat atas . Namun FOR JSON tingkat atas muncul sebagai nvarchar(max)

Setidaknya di CTP nama kolom khusus JSON masih berisi GUID F52E2B61-18A1-11d1-B105-00805F49916B terlepas dari kenyataan bahwa asal mula ini adalah Antarmuka IXMLDocument.

Paket terlihat hampir sama meskipun XML Select diganti dengan JSON Select

BTW:Di build Microsoft SQL Server 2014 - 12.0.4213.0 (X64) Saya tidak melihat perbedaan perilaku antara tabel temp dan tabel permanen. Ini mungkin karena @@Version yang berbeda antara lingkungan pertanyaan Anda menggunakan http://sqlfiddle.com/ (12.0.2000.8) dan https://data.stackexchange.com/ (12.0.4213.0).

Mungkin bug telah diperbaiki di sys.dm_exec_describe_first_result_set antara dua tahun 2014.

Pada 2012 saya mendapatkan hasil yang sama dengan Shnugo pada 11.0.5343.0 (dengan NULL di tiga baris pertama) tetapi setelah menginstal SP3 11.0.6020.0 saya mendapatkan hasil yang sama dengan hasil awal Anda yang ditunjukkan pada pertanyaan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengapa SQL Server mengabaikan ruang kosong di akhir secara otomatis?

  2. Periksa Apakah string berisi karakter beraksen dalam SQL?

  3. Cara Mereferensikan Kunci JSON yang Mengandung Karakter Khusus saat menggunakan OPENJSON, JSON_QUERY, dan JSON_VALUE (SQL Server)

  4. Hapus Data melalui Fungsi Bernilai Tabel di SQL Server

  5. Tambahkan Offset Zona Waktu ke Nilai datetime2 di SQL Server (T-SQL)