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 )
行是这样做的:
@sql_xml
是一个带有 XML
data-type 的 T-SQL 变量,这是一种“特殊”类型(与 int
或 date
,例如)因为它支持 方法 (在 OOP 意义上)。
- 调用
XML.nodes(XQuery)
方法,从 XML 文档结构中提取所有 <U>
元素。
-
nodes()
method is documented here 顺便说一句。
AS f( x )
部分是一个声明,它声明了一个名为 f
的新 派生 table,其中包含一个名为 x
映射到由 nodes()
方法提取的 <U>
元素。注意 x
的 data-type 仍然是 XML
.
.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.
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 )
行是这样做的:
@sql_xml
是一个带有XML
data-type 的 T-SQL 变量,这是一种“特殊”类型(与int
或date
,例如)因为它支持 方法 (在 OOP 意义上)。- 调用
XML.nodes(XQuery)
方法,从 XML 文档结构中提取所有<U>
元素。-
nodes()
method is documented here 顺便说一句。
-
AS f( x )
部分是一个声明,它声明了一个名为f
的新 派生 table,其中包含一个名为x
映射到由nodes()
方法提取的<U>
元素。注意x
的 data-type 仍然是XML
..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.