提问人:Pavel Andreev 提问时间:7/27/2022 最后编辑:marc_sPavel Andreev 更新时间:7/27/2022 访问量:220
分析 SQL Server 中的文本和特殊字符
Parse text and special characters from SQL Server
问:
我在 SQL Server 中使用 XML 中的特殊字符解析文本时遇到了问题。
假设我有一个 XML 文件,其中包含以下数据:Sample.xml
<People>
<Person FirstName="Adam"
LastName="Smith"
Age="44"
Weight="178">
<Texts>
<Text Country="US"
Language="EN"
TextType="1"><div>First sentence to retrieve.</div></Text>
<Text Country="GB"
Language="EN"
TextType="2"><div>Second sentence to retrieve.</div></Text>
</Texts>
</Person>
</People>
我准备了以下 SQL 脚本,它可以解析除属性中的两个句子之外的所有内容:<TextType>
- 要检索的第一句话
- 要检索的第二句话
DECLARE @x XML
SELECT @x = f FROM OPENROWSET(BULK 'C:\Sample.xml', single_blob) AS C(f)
DECLARE @hdoc int
EXEC sp_xml_preparedocument @hdoc OUTPUT, @x
SELECT * FROM OPENXML (@hdoc, '/People/Person/Texts/Text')
WITH (
FirstName varchar(max) '../../@FirstName'
, LastName varchar(max) '../../@LastName'
, Age varchar(max) '../../@Age'
, [Weight] varchar(max) '../../@Weight'
, Country varchar(max) '@Country'
, [Language] varchar(max) '@Language'
, TextType varchar(max) '@TextType'
)
EXEC sp_xml_removedocument @hdoc
你能帮我添加上面提到的句子的列吗?
答:
0赞
Charlieface
7/27/2022
#1
OPENXML
很旧,基本上被弃用了,它有很多问题。
您应该使用较新的 XQuery 函数并检索数据。.nodes
.value
您的主要问题是您将 XML 作为字符串存储在另一个 XML 中。您需要将其检索为 ,然后使用 强制转换。nvarchar(max)
TRY_CONVERT
SELECT
FirstName = x1.Person.value('@FirstName', 'varchar(100)'),
LastName = x1.Person.value('@LastName' , 'varchar(100)'),
Age = x1.Person.value('@Age' , 'int'),
Weight = x1.Person.value('@Weight' , 'decimal(9,5)'),
Country = x2.Text.value('@Country' , 'char(2)'),
[Language] = x2.Text.value('@Language', 'char(2)'),
TextType = x2.Text.value('@TextType', 'int'),
value = v.InnerXml.value('(div/text())[1]','nvarchar(max)')
FROM @x.nodes('People/Person') x1(Person)
CROSS APPLY x1.Person.nodes('Texts/Text') x2(Text)
CROSS APPLY (VALUES( TRY_CONVERT(xml, x2.Text.value('text()[1]','nvarchar(max)')) )) v(InnerXml);
请注意,有两个调用 ,一个调用馈送到下一个调用。.nodes
您甚至可以直接从OPENROWSET
SELECT
FirstName = x1.Person.value('@FirstName', 'varchar(100)'),
LastName = x1.Person.value('@LastName' , 'varchar(100)'),
Age = x1.Person.value('@Age' , 'int'),
Weight = x1.Person.value('@Weight' , 'decimal(9,5)'),
Country = x2.Text.value('@Country' , 'char(2)'),
[Language] = x2.Text.value('@Language', 'char(2)'),
TextType = x2.Text.value('@TextType', 'int'),
value = v.InnerXml.value('(div/text())[1]','nvarchar(max)')
FROM OPENROWSET(BULK 'C:\Sample.xml', single_blob) AS C(f)
CROSS APPLY (VALUES( TRY_CONVERT(xml, C.f) )) C2(AsXml)
CROSS APPLY C2.AsXml.nodes('People/Person') x1(Person)
CROSS APPLY x1.Person.nodes('Texts/Text') x2(Text)
CROSS APPLY (VALUES( TRY_CONVERT(xml, x2.Text.value('text()[1]','nvarchar(max)')) )) v(InnerXml);
我建议你修复生成这个XML的任何内容,理想情况下,你会在不字符串化的情况下传递内部XML。
评论