SQL Server存储过程读取xml文件

时间:2016-07-11 12:55:54

标签: sql-server xml

我有一个应用程序,我想列出所有匹配请求的过滤器类别的产品。我可以通过XML文件从c#代码发送所有过滤器。我的XML文件看起来像......

<filter CategoryId="" ForHomepage="" StartingIndex="">
<brand>
<id></id>
<id></id>
</brand>
<os>
<id></id>
<id></id>
</os>
<touch value="" />
<display>
<id></id>
<id></id>
</display>
<ram>
<id></id>
<id></id>
</ram>
<storage>
<id></id>
<id></id>
</storage>
<camera>
<id></id>
<id></id>
</camera>
<battery>
<id></id>
<id></id>
</battery>
</filter>

我可以读取XML并将数据存储在临时表中,但我想读取sp中声明的变量中的categoryid,touch,forhomepage和startingindex字段(因为这是非重复数据,所以不在表中)。

过去有人可以有这样的问题吗?将XML数据存储在声明的变量中。

取自OP的评论:

<filter CategoryId="12" ForHomepage="true" StartingIndex="0">
  <brand>
    <id>1001</id>
    <id>1006</id>
  </brand>
  <os>
    <id>7005</id>
    <id>7009</id>
  </os>
  <touch value="true" />
  <display>
    <id>3002</id>
    <id>3005</id>
  </display>
  <ram>
    <id>2006</id>
    <id>2009</id>
  </ram>
  <storage>
    <id>4006</id>
  </storage>
  <camera>
    <id>9009</id>
    <id>9014</id>
  </camera>
  <battery>
    <id>1501</id>
    <id>1581</id>
  </battery>
</filter>

1 个答案:

答案 0 :(得分:1)

这是 - 当然! - 不完全是你想要的(我只是不知道你将要做什么),但它应该指向正确的方向:

declare @xml XML=
'<filter CategoryId="12" ForHomepage="true" StartingIndex="0">
  <brand>
    <id>1001</id>
    <id>1006</id>
  </brand>
  <os>
    <id>7005</id>
    <id>7009</id>
  </os>
  <touch value="true" />
  <display>
    <id>3002</id>
    <id>3005</id>
  </display>
  <ram>
    <id>2006</id>
    <id>2009</id>
  </ram>
  <storage>
    <id>4006</id>
  </storage>
  <camera>
    <id>9009</id>
    <id>9014</id>
  </camera>
  <battery>
    <id>1501</id>
    <id>1581</id>
  </battery>
</filter>';

WITH MyValues AS
(
    SELECT flt.value('@CategoryId','int') AS CategoryId
          ,flt.value('@ForHomepage','bit') AS ForHomepage
          ,flt.value('@StartingIndex','int') AS StartingIndex
          ,elmt.value('local-name(.)','varchar(max)') AS Filter
          ,elmt.value('id[1]','int') AS ID1
          ,elmt.value('id[2]','int') AS ID2
    FROM @xml.nodes('/filter') AS A(flt)
    CROSS APPLY A.flt.nodes('*') AS B(elmt)
)
SELECT * FROM MyValues

结果

+------------+-------------+---------------+---------+------+------+
| CategoryId | ForHomepage | StartingIndex | Filter  | ID1  | ID2  |
+------------+-------------+---------------+---------+------+------+
| 12         | 1           | 0             | brand   | 1001 | 1006 |
+------------+-------------+---------------+---------+------+------+
| 12         | 1           | 0             | os      | 7005 | 7009 |
+------------+-------------+---------------+---------+------+------+
| 12         | 1           | 0             | touch   | NULL | NULL |
+------------+-------------+---------------+---------+------+------+
| 12         | 1           | 0             | display | 3002 | 3005 |
+------------+-------------+---------------+---------+------+------+
| 12         | 1           | 0             | ram     | 2006 | 2009 |
+------------+-------------+---------------+---------+------+------+
| 12         | 1           | 0             | storage | 4006 | NULL |
+------------+-------------+---------------+---------+------+------+
| 12         | 1           | 0             | camera  | 9009 | 9014 |
+------------+-------------+---------------+---------+------+------+
| 12         | 1           | 0             | battery | 1501 | 1581 |
+------------+-------------+---------------+---------+------+------+

更新

根据你的评论,你需要变量中的前三个......

使用与上面相同的XML变量并尝试:

DECLARE @CategoryId INT;
DECLARE @ForHomepage BIT;
DECLARE @StartingIndex INT;

SELECT @CategoryId=@xml.value('(/filter/@CategoryId)[1]','int')
      ,@ForHomepage=@xml.value('(/filter/@ForHomepage)[1]','bit')
      ,@StartingIndex=@xml.value('(/filter/@StartingIndex)[1]','int');

SELECT @CategoryId,@ForHomepage,@StartingIndex