Разбор или получение таблиц из столбца типа XML - PullRequest
1 голос
/ 27 сентября 2019

У меня есть столбец данных XML, который содержит тысячи записей / ячеек.Каждая ячейка в этом столбце имеет следующую форму (ниже показано, как выглядит одна ячейка - предположим, что это ячейка 3):

<Document>
  <Version>1</Version>
   <Section Name="General">
     <Value Name="Transaction type">CCM</Value>
     <Value Name="Description">Benjamin Capital</Value>
     <Value Name="Our likely role">Lead manager</Value>
     <Value Name="Target description">structure (Dec</Value>
     <Value Name="Previously submitted by email">No</Value>
   </Section>

  <Table Name="Team Members">
     <Headers>
       <Field Width="30">Name</Field>
       <Field Width="18">Country</Field>
       <Field Width="25">Department</Field>
       <Field Width="25">Role</Field>
     </Headers>
     <Row>
       <Field>Lincoln</Field>
       <Field>Australia</Field>
       <Field>Sales</Field>
       <Field>Manager</Field>
     </Row>
     <Row>
       <Field>Andrew</Field>
       <Field>Vietnam</Field>
       <Field>Estate</Field>
       <Field>Director</Field>
     </Row>
    </Table>

 <Table Name="Companies">
    <Headers>
      <Field Width="50">Party Name</Field>
      <Field Width="25">Role</Field>
      <Field Width="23">Contact Required?</Field>
    </Headers>
    <Row>
      <Field>A2 Milk</Field>
      <Field>Client</Field>
      <Field>Yes</Field>
    </Row>
    <Row>
      <Field>Citi Bank</Field>
      <Field>Client</Field>
      <Field>No</Field>
    </Row>
    <Row>
      <Field>McKinsey Co</Field>
      <Field>Provider</Field>
      <Field>No</Field>
    </Row>
    </Table>
</Document>

Как вы могли видеть, в одну ячейку встроены две таблицы: члены команды и компании,В идеале я хочу преобразовать эти две большие таблицы в этот формат, используя, возможно, два отдельных запроса:

Таблица членов команды

Cell No   |   Name     |  Country     | Department    |   Role
Cell 3    | Lincoln    |  Australia   |  Sales        |    Manager
Cell 3    | Andrew     |  Vietnam     | Estate        |   Director
Cell 4    | ....       |   ....       |  ...          |    ...
Cell 4    | ....       |  ....        |  ...          |    ...

Таблица компаний

Cell No   |   Party Name  |     Role    |  Contact_Required
Cell 3    |    A2 Milk    |    Client   |     Yes
Cell 3    |   Citi Bank   |   Client    |      Yes
Cell 3    |   McKinsey Co |   Provider  |       No
Cell 4    |  ....         |    ....     |     ...
Cell 4    |  ....         |    ....     |      ...
Cell 5    |  ....         |    ....     |     ...

Количество членов и компаний для каждой ячейки может быть разным.Пожалуйста, не могли бы вы помочь мне с этим.

1 Ответ

0 голосов
/ 27 сентября 2019

Боюсь, что нет ничего нестандартного.

T-SQL может быть неподходящим инструментом для этого ...

Необходимость имен переменных таблиц и столбцов требует динамическогосоздал SQL.Но вы можете попробовать кое-что по этому поводу:

Создать mockup-сценарий

DECLARE @mokupTable TABLE(ID INT,YourXmlColumn XML);
INSERT INTO @mokupTable VALUES
(1,N'<Document>
  <Version>1</Version>
   <Section Name="General">
     <Value Name="Transaction type">CCM</Value>
     <Value Name="Description">Benjamin Capital</Value>
     <Value Name="Our likely role">Lead manager</Value>
     <Value Name="Target description">structure (Dec</Value>
     <Value Name="Previously submitted by email">No</Value>
   </Section>

  <Table Name="Team Members">
     <Headers>
       <Field Width="30">Name</Field>
       <Field Width="18">Country</Field>
       <Field Width="25">Department</Field>
       <Field Width="25">Role</Field>
     </Headers>
     <Row>
       <Field>Lincoln</Field>
       <Field>Australia</Field>
       <Field>Sales</Field>
       <Field>Manager</Field>
     </Row>
     <Row>
       <Field>Andrew</Field>
       <Field>Vietnam</Field>
       <Field>Estate</Field>
       <Field>Director</Field>
     </Row>
    </Table>

 <Table Name="Companies">
    <Headers>
      <Field Width="50">Party Name</Field>
      <Field Width="25">Role</Field>
      <Field Width="23">Contact Required?</Field>
    </Headers>
    <Row>
      <Field>A2 Milk</Field>
      <Field>Client</Field>
      <Field>Yes</Field>
    </Row>
    <Row>
      <Field>Citi Bank</Field>
      <Field>Client</Field>
      <Field>No</Field>
    </Row>
    <Row>
      <Field>McKinsey Co</Field>
      <Field>Provider</Field>
      <Field>No</Field>
    </Row>
    </Table>
</Document>');

- Объявить таблицу для хранения сгенерированных команд

DECLARE @commands TABLE(ID INT IDENTITY,cmd NVARCHAR(MAX));

- Это вставит CREATE TABLE операторов

INSERT INTO @commands
SELECT CONCAT(N'CREATE TABLE dbo.',QUOTENAME(A.t.value('@Name','nvarchar(1000)')),N'('
             ,STUFF((SELECT CONCAT(',',QUOTENAME(B.f.value('text()[1]','nvarchar(1000)')),N' NVARCHAR(',B.f.value('@Width','int'),')' )
                     FROM A.t.nodes('Headers/Field') B(f)
                     FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,1,'')
             ,N');') 
FROM @mokupTable t
CROSS APPLY t.YourXmlColumn.nodes('/Document/Table') A(t)

- И это сгенерирует INSERT операторов

INSERT INTO @commands
SELECT CONCAT(N'INSERT INTO dbo.',QUOTENAME(A.t.value('@Name','nvarchar(1000)')),N'('
             ,STUFF((SELECT CONCAT(',',QUOTENAME(B.f.value('text()[1]','nvarchar(1000)')))
                     FROM A.t.nodes('Headers/Field') B(f)
                     FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,1,'')
             ,N') VALUES '
            ,STUFF((SELECT CONCAT(N',('
                                 ,STUFF((SELECT CONCAT(',''',QUOTENAME(C.f.value('text()[1]','nvarchar(1000)')),N'''' )
                                         FROM B.r.nodes('Field') C(f)
                                         FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,1,'')
                                 ,')')   
                    FROM A.t.nodes('Row') B(r)
                    FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,1,'')
             ,N';')
FROM @mokupTable t
CROSS APPLY t.YourXmlColumn.nodes('/Document/Table') A(t)

- Используйте CURSOR дляВыполните команды и распечатайте их для тестирования

DECLARE @cmd NVARCHAR(MAX);
DECLARE cur CURSOR FOR SELECT cmd FROM @commands ORDER BY ID;
OPEN cur;
FETCH NEXT FROM cur INTO @cmd;
WHILE @@FETCH_STATUS=0
BEGIN
    --Use EXEC(@cmd); to execute the statement
    PRINT @cmd;
    FETCH NEXT FROM cur INTO @cmd;  
END
CLOSE cur;
DEALLOCATE cur;

Код создаст и напечатает операторы, подобные этим

CREATE TABLE dbo.[Team Members]([Name] NVARCHAR(30),[Country] NVARCHAR(18),[Department] NVARCHAR(25),[Role] NVARCHAR(25));
CREATE TABLE dbo.[Companies]([Party Name] NVARCHAR(50),[Role] NVARCHAR(25),[Contact Required?] NVARCHAR(23));
INSERT INTO dbo.[Team Members]([Name],[Country],[Department],[Role]) VALUES ('[Lincoln]','[Australia]','[Sales]','[Manager]'),('[Andrew]','[Vietnam]','[Estate]','[Director]');
INSERT INTO dbo.[Companies]([Party Name],[Role],[Contact Required?]) VALUES ('[A2 Milk]','[Client]','[Yes]'),('[Citi Bank]','[Client]','[No]'),('[McKinsey Co]','[Provider]','[No]');

Просто используйте EXEC(@cmd); для выполнения этого.Используйте тестовую базу данных и попробуйте: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...