使用 OpenXML
Working with OpenXML
我正在将 XML 传递给 SQL 服务器存储过程并尝试将其存储在 #temp
table.
存储过程如下:
EXEC sp_xml_preparedocument @i OUTPUT
,@XMLDOC
SELECT Id
,UserId
,ModifiedOn
,ModifiedBy
,ModifiedIp
,DetailId
INTO #temp
FROM OPENXML(@i, '/Root/Rec/Detail', 1) WITH (
id INT '../@Id'
,UserId INT '../@UserId'
,ModifiedOn DATETIME '../@ModifiedOn'
,ModifiedBy INT '../@ModifiedBy'
,ModifiedIp VARCHAR(15) '../@ModifiedIp'
,DetailId INT '@DetailId'
)
EXEC sp_xml_removedocument @i
select * from #temp
和XML的样本:
<root>
<rec id="I001" userid="316" modifiedon="9/10/2016 02:33:56 PM" modifiedby="316" modifiedip="::1" UserDetail="System.Collections.Generic.List`1[Dto.UserDetail]">
</rec>
</root>
当XML 包含子节点(detail
)时,此SP 将正常工作。如果我没有子节点 - 它不会工作。你能指出我错在哪里吗?
完全重写答案:
DECLARE @i int,
@XMLDOC VARCHAR(max)= "INPUT XML"
EXEC sp_xml_preparedocument @i OUTPUT
,@XMLDOC
SELECT *
INTO #temp
FROM (
SELECT m.Id,
m.UserId,
m.ModifiedOn,
m.ModifiedBy,
m.ModifiedIp,
COALESCE(det.DetailId, -1) as DetailId
FROM OPENXML(@i, '/root/rec', 1) WITH (
id INT '@availabilityid',
UserId INT '@userid',
ModifiedOn DATETIME '@modifiedon',
ModifiedBy INT '@modifiedby',
ModifiedIp VARCHAR(15) '@modifiedip'
) as m
LEFT JOIN (
SELECT Id,
DetailId
FROM OPENXML(@i, '/root/rec/userturnarounddetail', 1) WITH (
id INT '../@availabilityid',
DetailId INT '@availabilitydetailid'
)
) as det
ON m.id =det.id
) p
EXEC sp_xml_removedocument @i
select * from #temp
输出:
Id UserId ModifiedOn ModifiedBy ModifiedIp DetailId
113367 316 2016-09-11 11:01:09.000 316 ::1 300100
0 316 2016-09-11 11:01:11.000 316 ::1 -1
编辑
.nodes
method 示例。自 SQL Server 2008 起可用。
DECLARE @XMLDOC xml
SELECT @XMLDOC =
'<root>
<rec id="I001" userid="316" modifiedon="9/10/2016 02:33:56 PM" modifiedby="316" modifiedip="::1" UserDetail="System.Collections.Generic.List1[Dto.UserDetail]">
</rec>
</root>'
SELECT ISNULL(d.f.value('@id','nvarchar(15)'),d.f.value('../@id','nvarchar(15)')) as id,
ISNULL(d.f.value('@userid','int'),d.f.value('../@userid','int')) as UserId,
ISNULL(d.f.value('@modifiedon','datetime'),d.f.value('../@modifiedon','datetime')) as ModifiedOn,
ISNULL(d.f.value('@modifiedby','int'),d.f.value('../@modifiedby','int')) as ModifiedBy,
ISNULL(d.f.value('@modifiedip','nvarchar(15)'),d.f.value('../@modifiedip','nvarchar(15)')) as ModifiedIp,
d.f.value('@detailid','int') as DetailId
FROM @XMLDOC.nodes('//*//*') as d(f)
我正在将 XML 传递给 SQL 服务器存储过程并尝试将其存储在 #temp
table.
存储过程如下:
EXEC sp_xml_preparedocument @i OUTPUT
,@XMLDOC
SELECT Id
,UserId
,ModifiedOn
,ModifiedBy
,ModifiedIp
,DetailId
INTO #temp
FROM OPENXML(@i, '/Root/Rec/Detail', 1) WITH (
id INT '../@Id'
,UserId INT '../@UserId'
,ModifiedOn DATETIME '../@ModifiedOn'
,ModifiedBy INT '../@ModifiedBy'
,ModifiedIp VARCHAR(15) '../@ModifiedIp'
,DetailId INT '@DetailId'
)
EXEC sp_xml_removedocument @i
select * from #temp
和XML的样本:
<root>
<rec id="I001" userid="316" modifiedon="9/10/2016 02:33:56 PM" modifiedby="316" modifiedip="::1" UserDetail="System.Collections.Generic.List`1[Dto.UserDetail]">
</rec>
</root>
当XML 包含子节点(detail
)时,此SP 将正常工作。如果我没有子节点 - 它不会工作。你能指出我错在哪里吗?
完全重写答案:
DECLARE @i int,
@XMLDOC VARCHAR(max)= "INPUT XML"
EXEC sp_xml_preparedocument @i OUTPUT
,@XMLDOC
SELECT *
INTO #temp
FROM (
SELECT m.Id,
m.UserId,
m.ModifiedOn,
m.ModifiedBy,
m.ModifiedIp,
COALESCE(det.DetailId, -1) as DetailId
FROM OPENXML(@i, '/root/rec', 1) WITH (
id INT '@availabilityid',
UserId INT '@userid',
ModifiedOn DATETIME '@modifiedon',
ModifiedBy INT '@modifiedby',
ModifiedIp VARCHAR(15) '@modifiedip'
) as m
LEFT JOIN (
SELECT Id,
DetailId
FROM OPENXML(@i, '/root/rec/userturnarounddetail', 1) WITH (
id INT '../@availabilityid',
DetailId INT '@availabilitydetailid'
)
) as det
ON m.id =det.id
) p
EXEC sp_xml_removedocument @i
select * from #temp
输出:
Id UserId ModifiedOn ModifiedBy ModifiedIp DetailId
113367 316 2016-09-11 11:01:09.000 316 ::1 300100
0 316 2016-09-11 11:01:11.000 316 ::1 -1
编辑
.nodes
method 示例。自 SQL Server 2008 起可用。
DECLARE @XMLDOC xml
SELECT @XMLDOC =
'<root>
<rec id="I001" userid="316" modifiedon="9/10/2016 02:33:56 PM" modifiedby="316" modifiedip="::1" UserDetail="System.Collections.Generic.List1[Dto.UserDetail]">
</rec>
</root>'
SELECT ISNULL(d.f.value('@id','nvarchar(15)'),d.f.value('../@id','nvarchar(15)')) as id,
ISNULL(d.f.value('@userid','int'),d.f.value('../@userid','int')) as UserId,
ISNULL(d.f.value('@modifiedon','datetime'),d.f.value('../@modifiedon','datetime')) as ModifiedOn,
ISNULL(d.f.value('@modifiedby','int'),d.f.value('../@modifiedby','int')) as ModifiedBy,
ISNULL(d.f.value('@modifiedip','nvarchar(15)'),d.f.value('../@modifiedip','nvarchar(15)')) as ModifiedIp,
d.f.value('@detailid','int') as DetailId
FROM @XMLDOC.nodes('//*//*') as d(f)