Обновление таблицы SQL из XML

#sql #xml #sql-update

#sql #xml #sql-update #sql-обновление

Вопрос:

Я использую InfoPath 2007 для отправки опроса (он не подключен к SharePoint или базе данных). Файл, который я получу обратно, является файлом XML. Каждое место, где есть блок ответов, имеет свой собственный уникальный идентификатор (он же имя поля).

Теперь у меня есть база данных SQL Server (2007?) с таблицей «Ответы». Ее столбцами являются: AnswerID (уникальный PK), QuestionID (FK) (который является уникальным идентификатором (именем поля) и Answer. Идентификатор вопроса уже заполнен уникальным идентификатором (имя поля). Для QuestionID имеется более 300 записей.

Что мне нужно сделать, это получить доступ к XML-файлу, найти QuestionID (имя поля), получить данные для этого имени поля, а затем поместить данные в столбец базы данных «Ответ», который соответствует имени поля в столбце QuestionID.

Есть ли простой / средний способ выполнить это сопоставление / обновление с наименьшей вероятностью ошибки?

ПРИМЕЧАНИЕ: Я попытался использовать мастер импорта XML-данных в БД, информация разбивается на неуправляемое количество таблиц.

Ответ №1:

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

 create table Responses(QuestionID varchar(10), Answer varchar(10))

insert into Responses values('Q1', null)
insert into Responses values('Q2', null)
insert into Responses values('Q3', null)

declare @xml xml
set @xml = 
'<root>
  <question ID="Q1">Answer1</question>
  <question ID="Q2">Answer2</question>
  <question ID="Q3">Answer3</question>
 </root>'

;with cte as
(
  select 
    r.n.value('@ID', 'varchar(10)') as QuestionID,
    r.n.value('.', 'varchar(10)') as Answer
  from @xml.nodes('/root/*') as r(n)
)
update R
set Answer = C.Answer
from Responses as R
  inner join cte as C
    on R.QuestionID = C.QuestionID

select *
from Responses 
  

Результат:

 QuestionID Answer
---------- ----------
Q1         Answer1
Q2         Answer2
Q3         Answer3
  

Используемый мной XML, безусловно, совсем не похож на тот, что есть у вас, но он должен дать вам подсказку о том, что вы можете сделать. Если вы опубликуете образец вашего XML-файла, структуру таблицы и ожидаемый результат / output, вы, вероятно, сможете получить более точный ответ.

Редактировать

 declare @xml xml = 
'<?xml version="1.0" encoding="UTF-8"?>
<my:myFields xmlns:my="xx.com" xml:lang="en-us">
  <my:group1>
    <my:group2>
      <my:field1>Im an analyst.</my:field1>
      <my:group3>
        <my:group4>
          <my:field2>1</my:field2>
          <my:field3>I click the mouse.</my:field3>
        </my:group4>
        <my:group4>
          <my:field2>2</my:field2>
          <my:field3>I type on the keyboard.</my:field3>
        </my:group4>
      </my:group3>
    </my:group2>
    <my:group2>
      <my:field1>Im a stay at home mom.</my:field1>
      <my:group3>
        <my:group4>
          <my:field2>1</my:field2>
          <my:field3>I Cook.</my:field3>
        </my:group4>
        <my:group4>
          <my:field2>2</my:field2>
          <my:field3>I clean.</my:field3>
        </my:group4>
      </my:group3>
    </my:group2>
  </my:group1>
</my:myFields>'

;with xmlnamespaces('xx.com' as my)
select 
  T.N.value('../../my:field1[1]', 'varchar(50)') as Field1,
  T.N.value('my:field2[1]', 'varchar(50)') as Field2,
  T.N.value('my:field3[1]', 'varchar(50)') as Field3
from @xml.nodes('my:myFields/my:group1/my:group2/my:group3/my:group4') as T(N)
  

Результат:

 Field1                 Field2       Field3
Im an analyst.          1           I click the mouse.
Im an analyst.          2           I type on the keyboard.
Im a stay at home mom.  1           I Cook.
Im a stay at home mom.  2           I clean.