SQL 如何从 xml 字符串中提取值

SQL how to extract value from xml string

CREATE FUNCTION split_string_XML
(
    @in_string VARCHAR(MAX),
    @delimiter VARCHAR(1)
)
RETURNS @list TABLE(NAMES VARCHAR(50))
AS
BEGIN
DECLARE @sql_xml XML = Cast('<root><U>'+ Replace(@in_string, @delimiter, '</U><U>')+ '</U></root>' AS XML)
    
    INSERT INTO @list(NAMES)
    SELECT f.x.value('.', 'VARCHAR(50)') AS NAMES
    FROM @sql_xml.nodes('/root/U') f(x)
    WHERE f.x.value('.', 'VARCHAR(50)') <> ''
    RETURN
END
GO

我无法理解以下行的语法和功能

 SELECT f.x.value('.', 'VARCHAR(50)')

这个'.'是什么意思表明它的用途是什么。

阅读您发布的代码时,f 不是很明显,因为作者没有使用明确的 AS 关键字。

所以这个:

INSERT INTO @list(NAMES)
SELECT f.x.value('.', 'VARCHAR(50)') AS NAMES
FROM @sql_xml.nodes('/root/U') f(x)
WHERE f.x.value('.', 'VARCHAR(50)') <> ''

可扩展为:

INSERT INTO
    @list( NAMES )
SELECT
    f.x.value( '.', 'VARCHAR(50)' ) AS NAMES
FROM
    @sql_xml.nodes('/root/U') AS f( x )  /*  `f` is declared here */
WHERE
    f.x.value('.', 'VARCHAR(50)') <> ''

@sql_xml.nodes('/root/U') AS f( x ) 行是这样做的:

  1. @sql_xml 是一个带有 XML data-type 的 T-SQL 变量,这是一种“特殊”类型(与 intdate,例如)因为它支持 方法 (在 OOP 意义上)。
  2. 调用 XML.nodes(XQuery) 方法,从 XML 文档结构中提取所有 <U> 元素。
  3. AS f( x ) 部分是一个声明,它声明了一个名为 f 的新 派生 table,其中包含一个名为 x 映射到由 nodes() 方法提取的 <U> 元素。注意 x 的 data-type 仍然是 XML.
  4. .value( path, type ) 方法提取指定的 path 并使用 type 类型公开它(在本例中为 varchar(50))。

也就是说,如果此函数用于将输入值列表拆分为 table,不要这样做Instead use table-valued parameters directly so you don't need to faff around with splitting strings.