将xml数据插入sql表

将xml数据插入sql表,sql,xml,import,Sql,Xml,Import,我有一个xml文档,格式如下: <response username="123" customerName="CustomerName" siteName="SiteName" customerID="123" Period="2009"> <topics> <topic name="MyTopic"> <department name="MyDepartment" parent="OriginalDepartment">

我有一个xml文档,格式如下:

<response username="123" customerName="CustomerName" siteName="SiteName" customerID="123" Period="2009">
  <topics>
    <topic name="MyTopic">
      <department name="MyDepartment" parent="OriginalDepartment">
        <questionHead result="Go" group="Group A" surveyID="1" questionID="2" responseID="3">
          <question>My Question</question>
          <answer>My Ansert</answer>
          <comment>Good Answer</comment>
          <reference>Page 10</reference>
        </questionHead>
        <questionHead result="Go" group="Group A" surveyID="1" questionID="2" responseID="3">
          <question>My Question</question>
          <answer>My Ansert</answer>
          <comment>Good Answer</comment>
          <reference>Page 10</reference>
        </questionHead>
因此,我已经将xml文件导入到一个带有xml列的临时表中,现在我正在尝试解析该文件并将其放入一个关系表中

以下是我正在尝试的:

INSERT INTO [SRCL_XmlTest].[dbo].[Questions]
           field list...
SELECT tab.col.value('./topic/@name', 'varchar(100)') as TopicName,
        tab.col.value('./topic/department/@name', 'varchar(100)') as DepartmentName,
        tab.col.value('./topic/department/@parent', 'varchar(100)') as ParentDepartmentName,
        tab.col.value('./topic/department/questionH/@questionID', 'int') as QuestionID,
        tab.col.value('./topic/department/questionH/@surveyID', 'int') as SurveyID,
        tab.col.value('./topic/department/questionH/@responseID', 'int') as ResponseID,
        tab.col.value('./topic/department/questionH/@pageNumber', 'int') as PageNumber,
        tab.col.value('./topic/department/questionH/@orderNumber', 'int') as OrderNumber,
        tab.col.value('./topic/department/questionH/@result', 'varchar(10)') as ResultColourCode,
        tab.col.value('./topic/department/questionH/@group', 'varchar(100)') as GroupName,
        tab.col.value('./topic/department/questionH/question', 'varchar(500)') as QuestionText,
        tab.col.value('./topic/department/questionH/answer', 'varchar(500)') as AnswerText,
        tab.col.value('./topic/department/questionH/comment', 'varchar(500)') as Comment,
        tab.col.value('./topic/department/questionH/reference', 'varchar(500)') as Reference
FROM FileImport
CROSS APPLY
XmlData.nodes('//response/topics') AS tab(col)
但是,我一直遇到错误:XQuery[FileImport.XmlData.value()]:“value()”需要一个单例(或空序列),找到的操作数类型为“xdt:untypedAtomic*”

这是因为xml中有多个主题节点?我已尝试将我的选择更改为: 节点('//response/topics/topic/department/questionHead/question')作为选项卡(col)


我现在可以访问这个问题,但无法接近答案。有什么想法吗?

尝试在
.value()
的xpath中使用
[1]
,例如:

tab.col.value('./topic[1]/@name', 'varchar(100)')
而不仅仅是

tab.col.value('./topic/@name', 'varchar(100)')

在每个xml.value中放置一个单例:

tab.col.value('(./topic)[1]/@name', 'varchar(100)')
tab.col.value('(./topic/department)[1]/@name', 'varchar(100)')
...
在没有XML模式声明的情况下,SQL无法猜测topics/topic是一个单例,所以您必须使用
(…)[1]
显式强制它

更新

如果XML中有多个父元素,则查询不正确。您需要将
主题
移动到
节点

SELECT
tab.col.value('@name',...)
tab.col.value('(./department)[1]',...)
...
FROM ...
CROSS APPLY ... nodes('//response/topics/topic') as tab(col);

通过这种方式,可以在“所有主题”节点中为每个主题投影一行。原始查询只能从每个主题父项中选择一个主题。

重复:可能应该是:
交叉应用。。。节点('/response/topics/topic')作为选项卡(col),没有?我怀疑
/topics/topic
XPath表达式会选择任何有用的东西。…@marc:在我的编辑中,我没有原始查询,所以我只是从内存中键入了。我会编辑以避免混淆。这不是确切的解决方案,但你让我走上了正确的道路。我的xpath需要是:
XmlData.nodes('//response/topics/topic/department/questionHead')作为tab(col)
。此外,我的选择列表还需要类似于(为简洁起见,请左键):
选择tab.col.value(“../../@name”,“varchar(100)”作为主题名,选择tab.col.value(“../@name”,“varchar(100)”作为部门名,选择tab.col.value(“@questionID”,“int”)作为问题ID,选择tab.col.value(“./question[1]”,选择“varchar(500)”)作为QuestionText
,本质上我需要转到most子节点,然后返回
SELECT
tab.col.value('@name',...)
tab.col.value('(./department)[1]',...)
...
FROM ...
CROSS APPLY ... nodes('//response/topics/topic') as tab(col);