TSQL中的XML解析会产生无效的列错误?

时间:2012-08-14 15:35:42

标签: sql-server xml tsql xml-parsing

我正在尝试解析一个简单的XML文件。只要我对插入语句发表评论,它就会给我带来无效的列错误。

drop table #TEMP
drop table #TEMP_T

declare @XMl_DATA AS XML
set @XMl_DATA =
'<DocumentElement>
  <Att_Table>
    <L_ATTR_CD>GAS_FLOW_START_DATE</L_ATTR_CD>
    <L_ATTR_DESC>GAS FLOW START DATE</L_ATTR_DESC>
    <L_ATTR_VALUE>01/01/2012</L_ATTR_VALUE>
    <R_ATTR_CD>EX_CTRCT_CO_ID</R_ATTR_CD>
    <R_ATTR_DESC>EXCLUDE GID(S)</R_ATTR_DESC>
    <R_ATTR_VALUE />
  </Att_Table>
  <Att_Table>
    <L_ATTR_CD>GAS_FLOW_END_DATE</L_ATTR_CD>
    <L_ATTR_DESC>GAS FLOW END DATE</L_ATTR_DESC>
    <L_ATTR_VALUE>01/31/2012</L_ATTR_VALUE>
    <R_ATTR_CD>EX_CTRCT_NBR</R_ATTR_CD>
    <R_ATTR_DESC>EXCLUDE CONTRACT NUMBER(S)</R_ATTR_DESC>
    <R_ATTR_VALUE />
  </Att_Table>
  <Att_Table>
    <L_ATTR_CD>CTRCT_CO_ID</L_ATTR_CD>
    <L_ATTR_DESC>GID(S)</L_ATTR_DESC>
    <L_ATTR_VALUE />
    <R_ATTR_CD>EX_RATE_CMPNT_CD</R_ATTR_CD>
    <R_ATTR_DESC>EXCLUDE RATE COMPONENT CODE(S)</R_ATTR_DESC>
    <R_ATTR_VALUE />
  </Att_Table>
  <Att_Table>
    <L_ATTR_CD>CTRCT_NBR</L_ATTR_CD>
    <L_ATTR_DESC>DART STYLE CONTRACT NUMBER(S)</L_ATTR_DESC>
    <L_ATTR_VALUE />
    <R_ATTR_CD>EX_PT_ID_NBR</R_ATTR_CD>
    <R_ATTR_DESC>EXCLIDE POINT ID NUMBER(S)</R_ATTR_DESC>
    <R_ATTR_VALUE />
  </Att_Table>
  </DocumentElement>'

临时表:

CREATE TABLE #TEMP_T 
    (
        ID INT IDENTITY(1,1), 
        ATT_CD VARCHAR(50), 
        ATT_CD_VALUE VARCHAR(1000)
    )

SELECT 
    cast(Colx.query('data(L_ATTR_CD)') as varchar(max))as L_ATTR_CD,
    cast(Colx.query('data(L_ATTR_VALUE)') as varchar(max))as L_ATTR_CD_VALUE,
    cast(Colx.query('data(R_ATTR_CD)') as varchar(max)) as R_ATTR_CD,
    cast(Colx.query('data(R_ATTR_VALUE)') as varchar(max))as R_ATTR_CD_VALUE
    INTO #TEMP 
    FROM @XMl_DATA.nodes('DocumentElement/Att_Table') AS T(Colx)

    --INSERT INTO #TEMP_T(ATT_CD,ATT_CD_VALUE)
    --SELECT LTRIM(RTRIM(L_ATT_CD)),LTRIM(RTRIM(L_ATT_CD_VALUE)) 
    --FROM #TEMP 
    --WHERE L_ATT_CD_VALUE <> 'NO_DATA'


    --INSERT INTO #TEMP_T(ATT_CD,ATT_CD_VALUE)
    --SELECT LTRIM(RTRIM(R_ATT_CD)),LTRIM(RTRIM(R_ATT_CD_VALUE)) 
    --FROM #TEMP 
    --WHERE R_ATT_CD_VALUE <>'NO_DATA'

输出:

     select * from #TEMP_T
        select * from #TEMP 

2 个答案:

答案 0 :(得分:1)

有时您会使用L_ATTRR_ATTR之类的内容,有时则会使用L_ATTR_ATT之类的内容(没有R s)。选择一个并坚持下去。

提及“无效列”的错误消息试图告诉您:您尝试从#TEMP中选择的列“无效”,因为您没有使用与创建时{{1}相同的名称}}

答案 1 :(得分:0)

你为什么不这样做呢?

-- define your XML structure and create the #TEMP_T table

;WITH ParsedData AS 
(
    SELECT
        Colx.value('(L_ATTR_CD)[1]', 'varchar(50)') as L_ATTR_CD,
        Colx.value('(L_ATTR_VALUE)[1]', 'varchar(50)') as L_ATTR_CD_VALUE,
        Colx.value('(R_ATTR_CD)[1]', 'varchar(50)') as R_ATTR_CD,
        Colx.value('(R_ATTR_VALUE)[1]', 'varchar(50)') as R_ATTR_CD_VALUE
    FROM 
        @XMl_DATA.nodes('DocumentElement/Att_Table') AS T(Colx)
)
INSERT INTO #temp_T(ATT_CD, ATT_CD_VALUE)
    SELECT L_ATTR_CD, L_ATTR_CD_VALUE
    FROM parseddata
    UNION
    SELECT R_ATTR_CD, R_ATTR_CD_VALUE
    FROM parseddata

这只是解析XML(比你的方法简单得多!)然后将(L_ATTR_CD, L_ATTR_CD_VALUE)和(R_ATTR_CD, R_ATTR_CD_VALUE)对同时插入到临时表中