簡體   English   中英

SQL Server:使用xquery時如何檢查xml中是否存在子節點

[英]SQL Server: How to check child node exist or not in xml when using xquery

這就是我在 XML 數據中迭代並從 XML 中提取值的方式。

我的 XML

<?xml version="1.0" encoding="utf-16"?>
<Root>
  <PeriodData>
    <PeriodType>ANNUALONLY</PeriodType>
    <Period>2010 FY</Period>
  </PeriodData>
  <PeriodData>
    <PeriodType>ANNUALONLY</PeriodType>
    <Period>2011 FY</Period>
    <IsDeleted/>
  </PeriodData>
  <PeriodData>
    <PeriodType>ANNUALONLY</PeriodType>
    <Period>2011 FY</Period>
    <IsDeleted>Y</IsDeleted>
  </PeriodData>  
</Root>

我在 SP 中的代碼,我在循環中迭代並通過 xquery 從 XML 中提取數據:

DECLARE @PeriodType VARCHAR(20), @Period VARCHAR(30), @IsDeleted CHAR(1)
DECLARE @MasterID INT
DECLARE @i INT, @cnt INT = @Periods.value('count(/Root/PeriodData)', 'INT');

SET @i = 1;
WHILE @i <= @cnt BEGIN

      SELECT @PeriodType = col.value('(PeriodType/text())[1]','VARCHAR(20)')
         , @Period = col.value('(Period/text())[1]','VARCHAR(30)')
         , @IsDeleted = col.value('(IsDeleted/text())[1]','VARCHAR(30)')
      FROM @Periods.nodes('/Root/PeriodData[position() = sql:variable("@i")]') AS tab(col);

      IF NOT EXISTS (SELECT * FROM tblCalenderDetail WHERE PeriodType=@PeriodType AND Period=@Period AND IsDeleted='Y')
      BEGIN
          INSERT INTO tblCalenderDetail (MasterID,PeriodType,Period,IsDeleted)
            VALUES(@MasterID,@PeriodType,@Period,'N')
      END
      ELSE
      BEGIN
        UPDATE tblCalenderDetail SET IsDeleted='N' WHERE PeriodType=@PeriodType AND Period=@Period
      END

   SET @i += 1;
END

請將isDeleted見子節點的第一條記錄不存在,請將isDeleted和子節點確實存在在第二排,但有空值。

那么在while循環中迭代時如何檢查IsDeleted子節點是否存在

我在下面的代碼中嘗試了這個來檢查IsDeleted 節點是否存在於每一行中,但沒有工作,而是拋出錯誤

@IsDeleted = IIF(col.exist('//IsDeleted') , col.value('(IsDeleted/text())[1]','VARCHAR(30)') ,'N')

在循環中,如果要檢查IsDeleted節點是否存在,則其值將存儲在@IsDeleted變量中。 如果節點不存在,那么我將在 @IsDeleted 變量中存儲“N” 如何實現這一目標?

請給我一些指導方針。

我得到了解決方案。 這我用ISNULL(col.value('(IsDeleted/text())[1]','VARCHAR(30)'), 'N')

完整的工作代碼

declare @xml xml=N'<?xml version="1.0" encoding="utf-16"?>
<Root>
  <PeriodData>
    <PeriodType>ANNUALONLY</PeriodType>
    <Period>2010 FY</Period>
  </PeriodData>
  <PeriodData>
    <PeriodType>ANNUALONLY</PeriodType>
    <Period>2011 FY</Period>
    <IsDeleted/>
  </PeriodData>
  <PeriodData>
    <PeriodType>ANNUALONLY</PeriodType>
    <Period>2011 FY</Period>
    <IsDeleted>Y</IsDeleted>
  </PeriodData>  
</Root>'

DECLARE @PeriodType VARCHAR(20), @Period VARCHAR(30), @IsDeleted CHAR(1)
        DECLARE @MasterID INT
        DECLARE @i INT, @cnt INT = @xml.value('count(/Root/PeriodData)', 'INT');

        SET @i = 1;
        WHILE @i <= @cnt BEGIN


              SELECT @PeriodType = col.value('(PeriodType/text())[1]','VARCHAR(20)')
                 , @Period = col.value('(Period/text())[1]','VARCHAR(30)')
                 , @IsDeleted = ISNULL(col.value('(IsDeleted/text())[1]','VARCHAR(30)'), 'N')
              FROM @xml.nodes('/Root/PeriodData[position() = sql:variable("@i")]') AS tab(col);

              PRINT @PeriodType + ' '+@Period+' '+@IsDeleted

           SET @i += 1;
        END

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM