Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

CHỌN CHO TỰ ĐỘNG XML và trả về các kiểu dữ liệu

FOR XML đã được giới thiệu trong SQL Server 2000.

SQL Server 2000 không có MAX kiểu dữ liệu hoặc XML loại dữ liệu. Cũng không thể sử dụng FOR XML trong một truy vấn phụ.

Bài viết Phía máy chủ FOR XML trả về gì? giải thích

Trong SQL Server 2000 ... FOR XML ... được thực hiện trong lớp mã giữa bộ xử lý truy vấn và lớp truyền tải dữ liệu ... bộ xử lý truy vấn tạo ra kết quả theo cách giống như khi không có FOR XML rồi đến FOR XML mã định dạng tập hợp hàng dưới dạng XML. Để có hiệu suất xuất bảnXML tối đa FOR XML thực hiện định dạng XML của tập hợp hàng kết quả và gửi trực tiếp đầu ra của nó tới TDScode phía máy chủ theo từng phần nhỏ mà không cần đệm toàn bộ XML trong không gian máy chủ. Kích thước phân đoạn là 2033 ký tự UCS-2. Do đó, các ký tự XML lớn hơn 2033UCS-2 được gửi đến phía máy khách trong nhiều hàng, mỗi hàng chứa một phần của XML. SQL Server sử dụng tên cột được xác định trước cho tập hợp hàng này với một cột thuộc loại NTEXT - “XML_F52E2B61-18A1-11d1-B105-00805F49916B ”- để chỉ ra tập hợp XMLrowset được phân khúc trong mã hóa UTF-16.

Vì vậy, có vẻ như điều này vẫn được triển khai theo cùng một cách đối với FOR XML cấp cao nhất trong các phiên bản mới hơn.

SQL Server 2005 đã giới thiệu khả năng sử dụng FOR XML trong các truy vấn con (có nghĩa là bây giờ chúng cần được xử lý bởi bộ xử lý truy vấn thay vì một lớp bên ngoài nó trong khi truyền trực tuyến kết quả đến máy khách)

Bài báo tương tự giải thích rằng chúng sẽ được nhập là NVARCHAR(MAX) hoặc XML phụ thuộc vào sự hiện diện hay không của một loại type chỉ thị.

Cũng như sự khác biệt về kiểu dữ liệu, điều này có nghĩa là SELECT bổ sung trình bao bọc có thể tạo ra sự khác biệt lớn về hiệu suất nếu #tab lớn.

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

Có thể thấy các cách tiếp cận khác nhau trong ngăn xếp cuộc gọi cũng như kế hoạch thực thi.

Được phát trực tiếp

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    

Với truy vấn phụ

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

Cả hai đều kết thúc việc gọi cùng một mã XML cơ bản nhưng phiên bản "chưa được gói" không có bất kỳ trình lặp XML nào trong chính kế hoạch, kết quả đạt được bằng cách thay thế các lệnh gọi phương thức từ CXStmtSelect với CXStmtXMLSelect thay vào đó (được trình bày trong kế hoạch dưới dạng nút gốc của Lựa chọn XML thay vì một Nút chọn cũ thuần túy).

Trên SQL Server 2016 CTP3, tôi vẫn thấy ntext cho cấp cao nhất FOR XML . Tuy nhiên, cấp cao nhất FOR JSON hiển thị dưới dạng nvarchar(max)

Ít nhất trong CTP, tên cột đặc biệt JSON vẫn chứa GUID F52E2B61-18A1-11d1-B105-00805F49916B mặc dù thực tế nguồn gốc của điều này là Giao diện tài liệu IXML.

Các kế hoạch trông giống nhau mặc dù Lựa chọn XML được thay thế bằng Lựa chọn JSON

BTW:Trên bản dựng Microsoft SQL Server 2014 - 12.0.4213.0 (X64) Tôi không thấy bất kỳ sự khác biệt nào về hành vi giữa bảng tạm thời và bảng vĩnh viễn. Đây có thể là do @@Version khác nhau giữa các môi trường mà câu hỏi của bạn sử dụng http://sqlfiddle.com/ (12.0.2000.8) và https://data.stackexchange.com/ (12.0.4213.0).

Có thể một lỗi đã được sửa trong sys.dm_exec_describe_first_result_set giữa hai bản dựng năm 2014.

Vào năm 2012, tôi nhận được kết quả tương tự như Shnugo trên 11.0.5343.0 (với NULL trong ba hàng đầu tiên) nhưng sau khi cài đặt SP3 11.0.6020.0, tôi nhận được kết quả giống như kết quả ban đầu của bạn được hiển thị trong câu hỏi.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách định dạng số dưới dạng tiền tệ trong SQL Server (T-SQL)

  2. Lấy dữ liệu từ quy trình được lưu trữ với Entity Framework

  3. Làm thế nào để gán một kết quả thực thi cho một biến sql?

  4. Cách áp dụng định dạng có điều kiện cho một số trong SQL Server bằng cách sử dụng FORMAT ()

  5. Không thể mở cơ sở dữ liệu mặc định người dùng. Đăng nhập thất bại. sau khi cài đặt SQL Server Management Studio Express