尝试了解为什么在 SQL Server 中使用 XML 节点函数时不能使用 sql_variant 作为值类型?我有一个场景,我将动态解析一些 XML 输入,并且能够使用 sql_variant 将是一个很好的替代方案,可以替代分配数据类型变量或在 sys.columns 上进行查找。
示例:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[XmlSourceTable]') AND type in (N'U'))
DROP TABLE [dbo].[XmlSourceTable]
GO
CREATE TABLE [dbo].[XmlSourceTable](
[RecordId] [int] IDENTITY(1,1) NOT NULL,
[XmlData] [xml] NOT NULL,
PRIMARY KEY CLUSTERED
(
[RecordId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
DECLARE @XML XML ='<?xml version="1.0" ?>
<Root>
<Person>
<Name>Simon</Name>
<Age>20</Age>
<Skills>
<Skill>Cooking</Skill>
<Skill>Cleaning</Skill>
</Skills>
</Person>
<Person>
<Name>Peter</Name>
<Age>21</Age>
<Skills>
<Skill>Ironing</Skill>
</Skills>
</Person>
</Root>'
INSERT INTO XmlSourceTable(XmlData)
SELECT @XML
GO
SELECT * FROM XmlSourceTable
GO
SELECT
pref.value('(Name/text())[1]', 'varchar(50)') as PersonName,
pref.value('(Age/text())[1]', 'int') as PersonAge,
pref.query('Skills') as PersonSkills
FROM
XmlSourceTable CROSS APPLY
XmlData.nodes('/Root/Person') AS People(pref)
所以代替:
SELECT * FROM XmlSourceTable
GO
SELECT
pref.value('(Name/text())[1]', 'varchar(50)') as PersonName,
pref.value('(Age/text())[1]', 'int') as PersonAge,
pref.query('Skills') as PersonSkills
FROM
XmlSourceTable CROSS APPLY
XmlData.nodes('/Root/Person') AS People(pref)
使用起来会很好:
SELECT * FROM XmlSourceTable
GO
SELECT
pref.value('(Name/text())[1]', 'sql_variant') as PersonName,
pref.value('(Age/text())[1]', 'sql_variantt') as PersonAge,
pref.query('Skills') as PersonSkills
FROM
XmlSourceTable CROSS APPLY
XmlData.nodes('/Root/Person') AS People(pref)
但我收到此错误: 消息 9500,16 级,状态 1,第 1 行 VALUE 方法中使用的数据类型“sql_variant)”无效。
是否可以在节点函数中使用 sql_variant?
谢谢
小
最佳答案
sql_variant
是一种元类型,它在值中存储数据的实际类型(int、char、float、date 等)。问题是 XML 表达式没有类型:像 ('Name/text())[1]
这样的 XPath 表达式结果的类型是什么?我理解您可能会说,如果 XML 有架构,就可以推断出与该节点/属性/元素关联的 xs 架构类型,但我想说也许您可以推断出类型,但仍然仍然使用着绝大多数无模式 XML 文档...这就是 .value()
XML 方法的原因需要一个类型,因此它可以将 XML 中找到的文本强制转换为正确的类型。
值得注意的一件事是,大多数 XML 值都可以提取为 VARCHAR
,这将给出该元素/属性的原始 XML 文本。然后您可以将文本转换为适当的列。但我认为现在做的事情(查找列类型,使用正确的类型动态构建 XPath/类型)更好。
关于SQL Server 2008 - XML 节点中的 sql_variant.value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3677980/