【问题标题】:Separating field into multiple columns XML/Varchar2/SQL将字段分成多列 XML/Varchar2/SQL
【发布时间】:2017-11-17 20:05:54
【问题描述】:

我正在使用从应用程序中提取数据的数据库。数据在字段中显示为 XML,但数据类型实际上是 varchar2。如何按括号中的名称将数据拆分为列?所以最终结果将是 中的每个名称将是列标题,而右括号和结束括号之间的值将是行数据。

例子:

列名:VAL_TXT

xml:<objects.CollegeInfo>
  <collegeOrgId>0000000000</collegeOrgId>
  <useCollegeOrgId>0000000000</useCollegeOrgId>
  <collegeName>University [City, ST, USA]</collegeName>
  <collegeCountry>USA</collegeCountry>
  <collegeState>ST</collegeState>
  <fromDate>08/15/2004</fromDate>
  <toDate>05/15/2007</toDate>
  <degreeDate>08/15/2008</degreeDate>
  <gpaType>4PT</gpaType>
  <gradePointAverage>3.5</gradePointAverage>
  <enteredDegree>Bachelor&apos;s</enteredDegree>
</objects.CollegeInfo>

每一行也可能有不同的字段。

此外,这些数据存储在 Oracle 服务器中,但我通过 MS SQL 上的链接服务器提取数据。

谢谢!

编辑:我确实尝试了以下方法

SELECT CAST(a.VAL_TXT as xml).value('(/objects.CollegeInfo/collegeOrgId)[1]','INT') AS col1
from TABLE a;

我收到错误消息:Msg 9403, Level 16, State 1, Line 1 XML 解析:第 0 行,第 0 字符,无法识别的输入签名

新编辑(第二次尝试):

SELECT *
FROM
    (
       SELECT
          VAL_TXT = CAST(VAL_TXT AS XML)
       FROM
          TABLE
    ) t
    CROSS APPLY
    (
       SELECT
          collegeOrgId = x.n.value('collegeOrgId[1]','varchar(20)')
          ,useCollegeOrgId = x.n.value('useCollegeOrgId[1]','varchar(50)')
          ,collegeName = x.n.value('collegeName[1]','VARCHAR(100)')
          ,collegeCountry = x.n.value('collegeCountry[1]','VARCHAR(20)')
          ,collegeState = x.n.value('collegeState[1]','CHAR(2)')
          ,fromDate = x.n.value('fromDate[1]','varchar(30)')
          ,toDate = x.n.value('toDate[1]','varchar(30)')
          ,degreeDate = x.n.value('degreeDate[1]','varchar(30)')
          ,gpaType = x.n.value('gpaType[1]','VARCHAR(20)')
          ,gradePointAverage = x.n.value('gradePointAverage[1]','DECIMAL(5,3)')
          ,enteredDegree = x.n.value('enteredDegree[1]','VARCHAR(20)')
       FROM
          t.VAL_TXT.nodes ('objects.CollegeInfo') as x(n)
    ) c;

收到错误: 消息 9411,第 16 层,状态 1,第 8 行 XML 解析:第 1 行,第 10 个字符,需要分号

【问题讨论】:

    标签: sql xml sql-server-2016 varchar2


    【解决方案1】:
    DECLARE @TableWithXMLAsVarchar AS TABLE (XMLasVarchar VARCHAR(MAX))
    INSERT INTO @TableWithXMLAsVarchar VALUES ('<objects.CollegeInfo>
      <collegeOrgId>0000000000</collegeOrgId>
      <useCollegeOrgId>0000000000</useCollegeOrgId>
      <collegeName>University [City, ST, USA]</collegeName>
      <collegeCountry>USA</collegeCountry>
      <collegeState>ST</collegeState>
      <fromDate>08/15/2004</fromDate>
      <toDate>05/15/2007</toDate>
      <degreeDate>08/15/2008</degreeDate>
      <gpaType>4PT</gpaType>
      <gradePointAverage>3.5</gradePointAverage>
      <enteredDegree>Bachelor&apos;s</enteredDegree>
    </objects.CollegeInfo>')
    
    
    SELECT *
    FROM
        (
           SELECT
              XMLColumn = CAST(XMLasVarchar AS XML)
           FROM
              @TableWithXMLAsVarchar
        ) t
        CROSS APPLY
        (
           SELECT
              collegeOrgId = x.n.value('collegeOrgId[1]','INT')
              ,useCollegeOrgId = x.n.value('useCollegeOrgId[1]','INT')
              ,collegeName = x.n.value('collegeName[1]','VARCHAR(100)')
              ,collegeCountry = x.n.value('collegeCountry[1]','VARCHAR(20)')
              ,collegeState = x.n.value('collegeState[1]','CHAR(2)')
              ,fromDate = x.n.value('fromDate[1]','DATE')
              ,toDate = x.n.value('toDate[1]','DATE')
              ,degreeDate = x.n.value('degreeDate[1]','DATE')
              ,gpaType = x.n.value('gpaType[1]','VARCHAR(20)')
              ,gradePointAverage = x.n.value('gradePointAverage[1]','DECIMAL(5,3)')
              ,enteredDegree = x.n.value('enteredDegree[1]','VARCHAR(20)')
           FROM
              t.XMLColumn.nodes ('objects.CollegeInfo') as x(n)
        ) c
    

    基本上,您的想法是正确的,但您必须从节点中选择值,而不是直接选择值。但是因为这些数据在表格中,所以您实际上还有更多工作要做。首先,您必须将列转换为 XML,但您不能在 FROM 语句中执行此操作,因此您可以通过 Common Table Expression [CTE] 或别名 Derived Table 执行此操作。之后您可以CROSS/OUTER APPLY 获取所有列。

    【讨论】:

    • 我更改了日期数据类型以避免一些当前的转换错误。更改这些后,我收到以下错误:Msg 9411, Level 16, State 1, Line 8 XML parsing: line 1, character 10, semicolon expected
    • @LindseyJackson 是的,您将不得不更改数据类型以匹配您的数据,只是想向您显示选项,以便您弄清楚。就分号而言,我必须查看您的代码才能知道语法差异是什么。如果您编辑您的问题并将其附加为当前尝试或其他内容,我很乐意看看。另外我想问题是你想在哪里运行它?这是假设您在 MS SQL 中运行它。这是您可以测试/播放的链接,以显示此代码按预期运行:rextester.com/RQV19377
    • 我在您的帮助下第二次尝试编辑帖子。我在 MS SQL 中运行它。出于安全原因,我显然已经为 TABLE 编辑了表名。几个字段也一样。
    • @LindseyJackson 我复制了粘贴的代码,没有问题。也许是因为您正在对链接服务器运行 ORACLE 查询?如果是这样,我不确定如何区别对待,不幸的是我无法测试。您可以将原始数据拉到 ms sql-server 上的临时表中,然后从那里查询...或者在 oracle 服务器上执行操作,然后拉出结果我确信 xml 方法在 Oracle 上会有所不同。 ...
    猜你喜欢
    • 2022-11-17
    • 2017-04-16
    • 2014-07-24
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多