将存储在另一个 table 的 varchar(max) 列中的 XML 文件中的数据插入 SQL table
Insert data into SQL table from XML file stored in varchar(max) column of another table
我的 table Table1.State varchar(max) 列包含一个 XML 文件,看起来像这样:
<?xml version="1.0"?><?xml-stylesheet type='text/xsl' href='MyObject.xsl'?>
<MyProperties>
<SortingState
Before="[{"Sorting":1
,"Type":4
,"Enabled":false}]"
After="[{"Sorting":2
,"Type":0
,"Enabled":true}]" />
<Appearance
Before="[{"Transparent":1
,"Color":Red
,"Border":10}]"
After="[{"Transparent":0
,"Color":Blue
,"Border":8}]]" />
</MyProperties>
我想知道如何将此 Table1.State 列读入临时 table 或 table 变量,以便将文件转换为 table,如下所示:
SortingState Before Sorting 1
SortingState Before Type 4
SortingState Before Enabled false
SortingState After Sorting 2
SortingState After Type 0
SortingState After Enabled true
Appearance Before Transparent 1
Appearance Before Color Red
Appearance Before Border 10
Appearance After Transparent 0
Appearance After Color Blue
Appearance After Border 8
好吧,这不是最漂亮的解决方案,但它会产生您请求的输出。我使用您提供的 XML 创建了一个 varchar(max)
变量 @XmlText
(为了包含在字符串文字中,将几个单引号更新为双单引号除外)。将其转换为 xml
数据类型的变量,然后解析:
DECLARE @XmlText varchar(max) =
'<?xml version="1.0"?><?xml-stylesheet type=''text/xsl'' href=''MyObject.xsl''?>
<MyProperties>
<SortingState
Before="[{"Sorting":1
,"Type":4
,"Enabled":false}]"
After="[{"Sorting":2
,"Type":0
,"Enabled":true}]" />
<Appearance
Before="[{"Transparent":1
,"Color":Red
,"Border":10}]"
After="[{"Transparent":0
,"Color":Blue
,"Border":8}]]" />
</MyProperties>';
DECLARE @Xml xml = CAST(@XmlText AS xml);
SELECT
my_properties_nodes.xml_frag.value('fn:local-name(.)','varchar(20)') AS Column1
,first_level_attributes.xml_frag.value('local-name(.)','varchar(10)') AS Column2
,SUBSTRING(RTRIM(LTRIM(ss.value)), CHARINDEX('"', RTRIM(LTRIM(ss.value)), 1) + 1, CHARINDEX('"', RTRIM(LTRIM(ss.value)), CHARINDEX('"', RTRIM(LTRIM(ss.value)), 1) + 1) - CHARINDEX('"', RTRIM(LTRIM(ss.value)), 1) - 1) AS Column3
,CASE
WHEN CHARINDEX('}', RTRIM(LTRIM(ss.value)), 1) > 1
THEN SUBSTRING(RTRIM(LTRIM(ss.value)), CHARINDEX(':', RTRIM(LTRIM(ss.value)), 1) + 1, CHARINDEX('}', RTRIM(LTRIM(ss.value)), 1) - CHARINDEX(':', RTRIM(LTRIM(ss.value)), 1) - 1)
ELSE RIGHT(RTRIM(LTRIM(ss.value)), LEN(RTRIM(LTRIM(ss.value))) - CHARINDEX(':', RTRIM(LTRIM(ss.value)), 1))
END AS Column4
FROM
@Xml.nodes('/MyProperties/*') AS my_properties_nodes(xml_frag)
CROSS APPLY my_properties_nodes.xml_frag.nodes('@*') AS first_level_attributes(xml_frag)
CROSS APPLY string_split(first_level_attributes.xml_frag.value('.','varchar(max)'), ',') AS ss;
查询从 MyProperties
元素正下方的每个子元素的一行开始,为第一个子元素的每个属性增加行,然后通过拆分的值再次增加行属性(使用 string_split
逗号。然后我只是手动解析值。Column3
在第一个和第二个 "
之间解析。Column4
在第一个 :
和字符串的结尾,或者第一个 :
和第一个 }
之间,具体取决于字符串是否包含 }
字符。
希望这对您有所帮助。
此外,您可以从包含此文本的 table 中使用它,就像使用 OUTER APPLY
将您的 varchar(max)
列转换为 xml
一样。然后将 CROSS APPLY
用于第一个 @Xml.nodes('/MyProperties/*') AS my_properties_nodes(xml_frag)
并将 @Xml
替换为对转换后的 xml 值的引用:
.......
FROM
MyTable AS tbl_a
OUTER APPLY (SELECT CAST(tbl_a.VarcharMaxColumn AS xml) AS ConvertedXml) AS cast_xml
CROSS APPLY cast_xml.ConvertedXml.nodes('/MyProperties/*') AS my_properties_nodes(xml_frag)
.......
我的 table Table1.State varchar(max) 列包含一个 XML 文件,看起来像这样:
<?xml version="1.0"?><?xml-stylesheet type='text/xsl' href='MyObject.xsl'?>
<MyProperties>
<SortingState
Before="[{"Sorting":1
,"Type":4
,"Enabled":false}]"
After="[{"Sorting":2
,"Type":0
,"Enabled":true}]" />
<Appearance
Before="[{"Transparent":1
,"Color":Red
,"Border":10}]"
After="[{"Transparent":0
,"Color":Blue
,"Border":8}]]" />
</MyProperties>
我想知道如何将此 Table1.State 列读入临时 table 或 table 变量,以便将文件转换为 table,如下所示:
SortingState Before Sorting 1
SortingState Before Type 4
SortingState Before Enabled false
SortingState After Sorting 2
SortingState After Type 0
SortingState After Enabled true
Appearance Before Transparent 1
Appearance Before Color Red
Appearance Before Border 10
Appearance After Transparent 0
Appearance After Color Blue
Appearance After Border 8
好吧,这不是最漂亮的解决方案,但它会产生您请求的输出。我使用您提供的 XML 创建了一个 varchar(max)
变量 @XmlText
(为了包含在字符串文字中,将几个单引号更新为双单引号除外)。将其转换为 xml
数据类型的变量,然后解析:
DECLARE @XmlText varchar(max) =
'<?xml version="1.0"?><?xml-stylesheet type=''text/xsl'' href=''MyObject.xsl''?>
<MyProperties>
<SortingState
Before="[{"Sorting":1
,"Type":4
,"Enabled":false}]"
After="[{"Sorting":2
,"Type":0
,"Enabled":true}]" />
<Appearance
Before="[{"Transparent":1
,"Color":Red
,"Border":10}]"
After="[{"Transparent":0
,"Color":Blue
,"Border":8}]]" />
</MyProperties>';
DECLARE @Xml xml = CAST(@XmlText AS xml);
SELECT
my_properties_nodes.xml_frag.value('fn:local-name(.)','varchar(20)') AS Column1
,first_level_attributes.xml_frag.value('local-name(.)','varchar(10)') AS Column2
,SUBSTRING(RTRIM(LTRIM(ss.value)), CHARINDEX('"', RTRIM(LTRIM(ss.value)), 1) + 1, CHARINDEX('"', RTRIM(LTRIM(ss.value)), CHARINDEX('"', RTRIM(LTRIM(ss.value)), 1) + 1) - CHARINDEX('"', RTRIM(LTRIM(ss.value)), 1) - 1) AS Column3
,CASE
WHEN CHARINDEX('}', RTRIM(LTRIM(ss.value)), 1) > 1
THEN SUBSTRING(RTRIM(LTRIM(ss.value)), CHARINDEX(':', RTRIM(LTRIM(ss.value)), 1) + 1, CHARINDEX('}', RTRIM(LTRIM(ss.value)), 1) - CHARINDEX(':', RTRIM(LTRIM(ss.value)), 1) - 1)
ELSE RIGHT(RTRIM(LTRIM(ss.value)), LEN(RTRIM(LTRIM(ss.value))) - CHARINDEX(':', RTRIM(LTRIM(ss.value)), 1))
END AS Column4
FROM
@Xml.nodes('/MyProperties/*') AS my_properties_nodes(xml_frag)
CROSS APPLY my_properties_nodes.xml_frag.nodes('@*') AS first_level_attributes(xml_frag)
CROSS APPLY string_split(first_level_attributes.xml_frag.value('.','varchar(max)'), ',') AS ss;
查询从 MyProperties
元素正下方的每个子元素的一行开始,为第一个子元素的每个属性增加行,然后通过拆分的值再次增加行属性(使用 string_split
逗号。然后我只是手动解析值。Column3
在第一个和第二个 "
之间解析。Column4
在第一个 :
和字符串的结尾,或者第一个 :
和第一个 }
之间,具体取决于字符串是否包含 }
字符。
希望这对您有所帮助。
此外,您可以从包含此文本的 table 中使用它,就像使用 OUTER APPLY
将您的 varchar(max)
列转换为 xml
一样。然后将 CROSS APPLY
用于第一个 @Xml.nodes('/MyProperties/*') AS my_properties_nodes(xml_frag)
并将 @Xml
替换为对转换后的 xml 值的引用:
.......
FROM
MyTable AS tbl_a
OUTER APPLY (SELECT CAST(tbl_a.VarcharMaxColumn AS xml) AS ConvertedXml) AS cast_xml
CROSS APPLY cast_xml.ConvertedXml.nodes('/MyProperties/*') AS my_properties_nodes(xml_frag)
.......