2016-09-10 2 views
1

Ich übergebe XML an gespeicherte Prozedur SQL Server und versuche, es in Tabelle zu speichern.Mit OpenXML arbeiten

Die gespeicherte Prozedur ist unten angegeben:

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 

und die Probe von 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> 

Wenn die XML-Kind-Knoten enthält (detail), wird dieser SP funktionieren. Wenn ich keine Kindknoten habe, wird es nicht funktionieren. Können Sie darauf hinweisen, wo ich falsch gelaufen bin?

+0

Wenn das XML untergeordnete Knoten enthält, wird dieses SP einwandfrei funktionieren. Wenn ich keine Kind-Knoten habe, wird es nicht funktionieren –

+0

Dies sieht aus wie ein [XY-Problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Die ganze Frage schreit "falsche Herangehensweise!". Zunächst einmal: 'FROM OPENXML' ist veraltet und sollte nicht mehr verwendet werden. Es gibt viel bessere Methoden. Zweitens, wenn Sie mit 'XML' arbeiten wollen, sollten Sie den entsprechenden Datentyp verwenden, nicht' VARCHAR (MAX) '(was noch schlimmer ist, da Sonderzeichen nicht korrekt behandelt werden). Ich schlage vor: Starten Sie eine neue Frage. Erkläre, was du hast, erkläre, was du willst und was du bisher versucht hast. Geben Sie ein Beispiel und die erwartete Ausgabe an. – Shnugo

Antwort

1

Völlig Rewrite Antwort:

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 

Ausgang:

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 

EDIT

Beispiel mit .nodesmethod. Es ist seit SQL Server 2008 verfügbar.

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) 
+0

Ich erhalte den Fehler "Die XMLDT-Methode 'Knoten' können nur für Spalten vom Typ XML aufgerufen werden", wenn ich versuche, Ihren ersten Code zu schreiben. Was könnte das Problem sein? –

+0

Was ist der Datentyp der Variable xmldoc? Es sollte XML sein. – gofr1

+0

Ich habe VARCHAR (MAX) in XML für den Eingabeparameter der gespeicherten SQL-Prozedur geändert. Aber während der Ausführung der sp, bekomme ich "Ungültiger Objektname 'd'" –