Динамический XML в SQL - SQL Server

У меня очень сложный XML, я просто пытаюсь написать динамический SQL-запрос для вставки данных в базу данных SQL Server из XML.

Ниже представлен XSD XML:

<xs:element name = "Department">
    <xs:complexType>
        <xs:all>
            <xs:element name = "DeptID" type = "xs:string" minOccurs = "0" maxOccurs = "1" />
            <xs:element name = "DepRefNum" type = "xs:string" minOccurs = "0" maxOccurs = "1" />
            <xs:element ref = "date"/>            
            <xs:element ref = "Employees" minOccurs = "0" maxOccurs = "1"/>
        </xs:all>
    </xs:complexType>
</xs:element>

<xs:element name = "Employees">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref = "Employee" minOccurs = "0" maxOccurs = "unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:element name = "Employee">
    <xs:complexType>
        <xs:sequence>
            <xs:element name = "Name" minOccurs = "0" maxOccurs = "1"/>
            <xs:element name = "Code" type = "xs:string" minOccurs = "0" maxOccurs = "1"/>
            <xs:element ref = "Date" minOccurs = "0" maxOccurs = "1"/>            
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:element name = "Date" type = "TypeStringWithTypeAttribute"/>

<xs:complexType name = "TypeStringWithTypeAttribute">
    <xs:simpleContent>
        <xs:extension base = "xs:string">
            <xs:attribute name = "type" type = "xs:string"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

Это образец XML:

<Department>
   <DeptID>D101</DeptID>
   <DepRefNum></DepRefNum>
   <Date type = "Create">01/1/2017 12:30</Date>
   <Employees>
         <Employee>
             <Name>Jason</Name>
             <Code>J111</Code>
             <Date type = "DOJ">06/18/2018 14:36</Date>
         </Employee>
         <Employee>
              <Name>Roy</Name>
              <Code>R111</Code>
              <Date type = "DOJ">06/18/2018 14:36</Date>
         </Employee>
    </Employees>   
</Department>

У меня есть 2 таблицы, и я пытаюсь получить данные в формате ниже, где Dept_ID взят из XML, но EMP_ID является идентификатором, и я хочу, чтобы Dept_ID использовался в качестве внешнего ключа, это не проблема, а только для информации :

отделение:

Dept_ID     Dept_Ref_Num    Create_Date_Type    Create_Date
---------------------------------------------------------------
D101                        Create              01/1/2017 12:30

Сотрудники:

Emp_ID   Dept_ID    Emp_Name    Emp_Code    Date_Type   Date
-------------------------------------------------------------------------
   1     D101       Jason       J111        DOJ         06/18/2018 14:36
   2     D101       Roy         R111        DOJ         06/18/2018 14:36

Я столкнулся с проблемами, потому что это динамический xml, я не знаю, сколько сотрудников будет там в реальном времени xml, то есть потому, что сотрудник под сотрудниками неограничен.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Исправлены закрывающие теги в XML.

Возможно что-то вроде этого:

Пример

Declare @XML xml = '
<Department>
   <DeptID>D101</DeptID>
   <DepRefNum></DepRefNum>
   <Date type = "Create">01/1/2017 12:30</Date>
   <Employees>
         <Employee>
             <Name>Jason</Name>
             <Code>J111</Code>
             <Date type = "DOJ">06/18/2018 14:36</Date>
         </Employee>
         <Employee>
              <Name>Roy</Name>
              <Code>R111</Code>
              <Date type = "DOJ">06/18/2018 14:36</Date>
         </Employee>
    </Employees>   
</Department>
'

Select DeptID    = lvl1.n.value('DeptID[1]','varchar(150)') 
      ,DepRefNum = lvl1.n.value('DepRefNum[1]','varchar(150)') 
      ,Create_Date_Type = lvl1.n.value('Date[1]/@type','varchar(150)') 
      ,Create_Date = lvl1.n.value('Date[1]','varchar(150)') 
 From  @XML.nodes('*') lvl1(n)

Select DeptID    = lvl1.n.value('DeptID[1]','varchar(150)') 
      ,Emp_Name  = lvl2.n.value('Name[1]','varchar(150)') 
      ,Emp_Code  = lvl2.n.value('Code[1]','varchar(150)') 
      ,Date_Type = lvl2.n.value('Date[1]/@type','varchar(150)') 
      ,Date      = lvl2.n.value('Date[1]','varchar(150)') 
 From  @XML.nodes('*') lvl1(n)
 Cross Apply lvl1.n.nodes('Employees/*') lvl2(n)

Возврат

DeptID      DepRefNum   Create_Date_Type    Create_Date
D101                    Create              01/1/2017 12:30

а также

DeptID  Emp_Name    Emp_Code    Date_Type   Date
D101    Jason       J111        DOJ         06/18/2018 14:36
D101    Roy         R111        DOJ         06/18/2018 14:36

Я просто надеюсь, что xml OP не в том состоянии, в котором он находится в их сообщении, иначе они сохранят его как varchar, и им будет кошмар, преобразовав его в xml.

Larnu 01.07.2018 21:25

@Larnu Надеюсь, ты прав. :) А пока я предполагаю, что это плохая копия / вставка.

John Cappelletti 01.07.2018 21:28

@John Cappelletti .. Большое спасибо :)

user7739833 02.07.2018 13:37

Вам не нужен динамический SQL для извлечения данных здесь. Вам просто нужно запросить правильный узел и получить доступ к родительскому объекту, например:

DECLARE @x XML='<Department>
   <DeptID>D101</DeptID>
   <DepRefNum></DepRefNum>
   <Date type = "Create">01/1/2017 12:30</Date>
   <Employees>
         <Employee>
             <Name>Jason</Name>
             <Code>J111</Code>
             <Date type = "DOJ">06/18/2018 14:36</Date>
         </Employee>

         <Employee>
              <Name>Roy</Name>
              <Code>R111</Code>
              <Date type = "DOJ">06/18/2018 14:36</Date>
         </Employee>
    </Employees>
</Department>'

SELECT  n.value('DeptID[1]','varchar(10)') AS DeptID,
        n.value('DepRefNum[1]','varchar(10)') AS DepRefNum,
        n.value('Date[1]/@type','varchar(10)') AS Create_Date_Type,
        n.value('Date[1]','datetime') AS Create_Date
FROM @x.nodes('/Department') R(n)

SELECT  n.value('../../DeptID[1]','varchar(10)') AS DeptID,
        n.value('Name[1]','varchar(10)') AS Emp_Name,
        n.value('Code[1]','varchar(10)') AS Emp_Code,
        n.value('Date[1]/@type','varchar(10)') AS Date_Type,
        n.value('Date[1]','datetime') AS Date
FROM @x.nodes('/Department/Employees/Employee') R(n)

Другие вопросы по теме