sql - 如何在T-SQL的XML类型中使用&字符?

标签 sql sql-server xml t-sql escaping

当我运行时:

SELECT name + '&' 
FROM sys.databases 
FOR XML PATH('');

代码返回:

master&tempdb&model&msdb&

我真正想要的是:

master&tempdb&model&msdb&

我也尝试过:

SELECT name + CHAR(38) 
FROM sys.databases 
FOR XML PATH(''); 

这也行不通。我怎样才能首先得到预期的结果?

没有类似的东西:

REPLACE(CAST('master&amp...l&msdb&' AS NVARCHAR(MAX)), '&', '&')

最佳答案

FOR XML 子句默认返回文本,因此结果字符串包含 XML 预定义实体引用,例如用于表示 & 符号的 &,以表示 XML 中的特殊字符。

要避免结果中出现实体引用,请在 FOR XML 子句中包含 TYPE,以将值返回为强类型 XML 而不是文本,这样就可以调用XML 节点上的 value 方法,在没有实体引用的情况下获取 nvarchar(MAX) 值:

SELECT (
    SELECT name + '&'
    FROM sys.databases
    FOR XML PATH(''), TYPE
    ).value('(./text())[1]', 'nvarchar(MAX)');

上面的示例包含一个尾随与号,就像您的原始查询一样。避免无关分隔符的一种方法是使用 STUFF。下面是另一个示例,它将分隔符添加到每个值并删除不需要的第一个分隔符。另外,单例节点值(./text())[1]规范将提高性能,这是一个考虑因素 对于更大的查询。

SELECT STUFF((
    SELECT '&' + name
    FROM sys.databases
    FOR XML PATH(''), TYPE
    ).value('(./text())[1]', 'nvarchar(MAX)'), 1, 1, '');

我要补充的是,您可以使用更简洁、更简洁的 STRING_AGG 技术来避免 SQL Server 2017+ 和 Azure SQL 数据库中聚合字符串连接的 XML 丑陋:

SELECT STRING_AGG(name, '&')
FROM sys.databases;

参见this answer有关使用 FOR XML 进行字符串聚合的更详细说明。

关于sql - 如何在T-SQL的XML类型中使用&字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53567452/

相关文章:

SQL 查询使用 Between 进行日期搜索

c# - 如何使用 ORMlite 将 byte[] 数组插入图像列

java - Android效果波纹圆圈imageView

sql查询显示状态代码而不使用状态代码表

java - 使用 JDom 格式化 XML,每行一个属性

xml - 在 vbscript 中选择具有属性名称的单个节点

mysql - 如何删除所有以某个前缀开头的MySQL表?

php - MySQL从多个表查询?

c# - 使用 LINQ 在两个日期和时间之间进行搜索

sql-server - 索引 SQL Server 上的 rowversion/timestamp 列的后果