Sql 选择XML自动和返回数据类型
在玩Sql 选择XML自动和返回数据类型,sql,sql-server,xml,tsql,sql-server-2012,Sql,Sql Server,Xml,Tsql,Sql Server 2012,在玩sys.dm\u exec\u description\u first\u result\u set时我说到这一点: CREATE TABLE #tab(col INT, x XML ); INSERT INTO #tab(col,x) VALUES (1,NULL), (2,NULL), (3,'<a>x</a>'); SELECT 'Simple XML' AS description, name, system_type_name FROM sys.dm_ex
sys.dm\u exec\u description\u first\u result\u set时
我说到这一点:
CREATE TABLE #tab(col INT, x XML );
INSERT INTO #tab(col,x) VALUES (1,NULL), (2,NULL), (3,'<a>x</a>');
SELECT 'Simple XML' AS description, name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT col
FROM #tab
FOR XML AUTO', NULL, 0)
UNION ALL
SELECT 'Wrapped with subquery', name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT(SELECT col
FROM #tab
FOR XML AUTO) AS wrapped_subquery', NULL, 0)
UNION ALL
SELECT 'XML column', name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT x FROM #tab ', NULL, 0)
UNION ALL
SELECT 'Casted XML', name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT CAST(''<o>O</o>'' AS XML) AS x', NULL, 0)
UNION ALL
SELECT 'Wrapped Casted XML', name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT (SELECT CAST(''<o>O</o>'' AS XML) AS x) AS wrapped', NULL, 0)
UNION ALL
SELECT 'Text value', name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT CAST(''aaa'' AS NTEXT) AS text_string', NULL, 0)
UNION ALL
SELECT 'Wrapped Text Value', name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT (SELECT CAST(''aaa'' AS NTEXT)) AS text_string_wrapped', NULL, 0)
以及:
问题:
不返回XML/NVARCHAR(MAX)
datatype,而返回ntext
(不推荐使用的数据类型!)
ntext
更改为nvarchar(max)
XML/NTEXT
列ntext
:
╔════════════════════════╦═══════════════════════════════════════╦══════════════════╗
║ description ║ name ║ system_type_name ║
╠════════════════════════╬═══════════════════════════════════════╬══════════════════╣
║ Simple XML ║ XML_F52E2B61-18A1-11d1-B105-00805F499 ║ ntext ║
║ Wrapped with subquery ║ wrapped_subquery ║ ntext ║
║ XML column ║ x ║ ntext ║
║ Casted XML ║ x ║ ntext ║
║ Wrapped Casted XML ║ wrapped ║ ntext ║
║ Text value ║ text_string ║ ntext ║
║ Wrapped Text Value ║ text_string_wrapped ║ ntext ║
╚════════════════════════╩═══════════════════════════════════════╩══════════════════╝
根据:
SQL Server对xml(Transact-SQL)的支持使您可以选择
通过指定type指令,请求将FOR-XML查询的结果作为XML数据类型返回
SQL Server将XML数据类型实例数据作为
不同服务器构造的结果,例如使用
TYPE指令,或使用xml数据类型返回xml的位置
SQL表列和输出参数中的实例数据值。在里面
客户端应用程序代码,ADO.NET提供程序请求此XML数据
键入要从服务器以二进制编码发送的信息。
但是,如果在没有TYPE指令的情况下使用FOR XML,则
数据以字符串类型返回
以及:
ntext
不是nvarchar(max)
与quote一样,XML数据以字符串类型返回
,而normal/temp表的差异在哪里有趣的问题!
NTEXT
真奇怪
关于子查询,我有一个想法:当您返回XML时,它会被转换为字符串,除非您指定类型
(您肯定知道这是通过交叉应用的嵌套XML或通过字符串连接STUFF实现的,有时您会看到类型
和后面的值()
——有时还会看到“裸”
我无法真正复制您的结果(SQL Server 2012也是如此)。简单的复制粘贴返回(我想用声明的表变量和函数的返回值进行测试):
编辑:有一个新的观察结果我认为不清楚,但这是我的错误…把它拿走了…
FOR XML
是在SQL Server 2000中引入的
SQL Server 2000没有MAX
数据类型或XML
数据类型。在子查询中也不可能对XML使用
文章解释道
在SQL Server 2000中…FOR XML
…是
在查询处理器和
数据传输层…查询处理器产生结果的方式与不产生结果的方式相同
用于XML
,然后用于XML
将行集格式化为XML。对于最大
XML的XML发布性能FOR XML
对
生成的行集并直接将其输出发送到服务器端TDS
代码分小块编写,而不在服务器空间中缓冲整个XML。
块大小为2033个UCS-2字符。因此,XML大于2033个字符
UCS-2字符以多行的形式发送到客户端
SQL Server使用预定义的列
此行集的名称,其中一列的类型为NTEXT
-
“XML_F52E2B61-18A1-11d1-B105-00805F49916B
”–表示分块的XML
UTF-16编码中的行集
因此,在以后的版本中,对于XML的顶级来说,这似乎也是以同样的方式实现的
SQL Server 2005引入了在子查询中对XML使用的功能(这意味着这些查询现在需要由查询处理器处理,而不是由查询处理器外部的一层处理,同时将结果流式传输到客户端)
同一篇文章解释说,根据是否存在类型
指令,它们将被键入为NVARCHAR(MAX)
或XML
除了数据类型的差异之外,这确实意味着如果#tab
很大,那么额外的SELECT
包装器可以在性能上产生巨大的差异
/*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
可以在调用堆栈和执行计划中看到不同的方法
直接流式传输
sqllang.dll!CXMLExecContext::AddTagAndAttributes()+0x5a9字节
sqllang.dll!CXMLExecContext::AddXMLRow()+0x2b7字节
sqltses.dll!CEsExec::FastMoveEval()+0x9c字节
sqllang.dll!CXStmtQuery::ErsqExecuteQuery()+0x280字节
sqllang.dll!CXStmtXMLSelect::WrapExecute()+0x2d7字节
sqllang.dll!CXStmtXMLSelect::XretDoExecute()+0x355字节
sqllang.dll!CXStmtXMLSelect::XretExecute()+0x46字节
sqllang.dll!CMsqlExecContext::ExecuteStmts()+0x368字节
sqllang.dll!CMsqlExecContext::FExecute()+0x6cb字节
sqllang.dll!CSQLSource::Execute()+0x3ee字节
sqllang.dll!处理_请求()+0x757字节
带子查询
sqllang.dll!CXMLExecContext::AddTagAndAttributes()+0x5a9字节
sqllang.dll!CXMLExecContext::AddXMLRow()+0x2b7字节
sqllang.dll!CForXmlSerialize::ProcessRow()+0x19字节
sqllang.dll!CUDXR_Base::PushRow()+0x30字节
sqlmin.dll!CQScanUdx::Open()+0xd5字节
sqlmin.dll!CQueryScan::StartupQuery()+0x170字节
sqllang.dll!cxsmtquery::SetupQueryScanAndExpression()+0x391字节
sqllang.dll!cxsmtquery::InitForExecute()+0x34字节
sqllang.dll!cxsmtquery::ErsqExecuteQuery()+0x217字节
sqllang.dll!cxsmtselect::XretExecute()+0xed字节
╔════════════════════════╦═══════════════════════════════════════╦══════════════════╗
║ description ║ name ║ system_type_name ║
╠════════════════════════╬═══════════════════════════════════════╬══════════════════╣
║ Simple XML ║ XML_F52E2B61-18A1-11d1-B105-00805F499 ║ ntext ║
║ Wrapped with subquery ║ wrapped_subquery ║ ntext ║
║ XML column ║ x ║ ntext ║
║ Casted XML ║ x ║ ntext ║
║ Wrapped Casted XML ║ wrapped ║ ntext ║
║ Text value ║ text_string ║ ntext ║
║ Wrapped Text Value ║ text_string_wrapped ║ ntext ║
╚════════════════════════╩═══════════════════════════════════════╩══════════════════╝
SELECT 'Simple XML' AS description, name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT col AS col
FROM #tab
FOR XML AUTO, TYPE', NULL, 0)
UNION ALL
SELECT 'Wrapped with subquery', name, system_type_name
FROM sys.dm_exec_describe_first_result_set(
N'SELECT(SELECT col
FROM #tab
FOR XML AUTO,TYPE) AS wrapped_subquery', NULL, 0);
Simple XML NULL NULL
Wrapped with subquery NULL NULL
XML column NULL NULL
Casted XML x xml
Wrapped Casted XML wrapped xml
Text value text_string ntext
Wrapped Text Value text_string_wrapped ntext
/*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
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
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