2016-04-07 2 views
2

У меня есть таблица, содержащая запрос формата XML. Для например:Как выполнить xml-анализ в процедуре хранения

Api_id xmlRequest Sent_Time 
1  ........ 07-04-2016 10:07:12:345 
1  ........ 08-04-2016 10:03:12:345 
2  ........ 09-04-2016 10:08:12:345 
2  ........ 09-04-2016 10:09:12:345 

Для api_id, мы можем иметь несколько запрос.

Схема запроса XML такая же, но имеет разные значения. запроса Xml как:

<?xml version="1.0"?> 
<!DOCTYPE PARTS SYSTEM "parts.dtd"> 
<PARTS> 
    <TITLE>Computer Parts</TITLE> 
    <PART> 
     <ITEM>Motherboard</ITEM> 
     <MANUFACTURER>ASUS</MANUFACTURER> 
     <MODEL>P3B-F</MODEL> 
     <COST> 123.00</COST> 
    </PART> 
</PARTS> 

мне нужна процедура магазина, так что я могу отправить api_id и значение (которое я могу искать в запросе XML) и получить запросы XML, основанные на стоимости товара.

CREATE PROCEDURE getxmlRequest(
     @Api_Id INT 
     @value 
     ,@xmlRequest VARCHAR(max) out) 
AS 
BEGIN 
     Set @xmlRequest = SELECT xmlRequest FROM Api_request 
      WHERE Api_id = @Api_id 
     /* here need to iterate over @xmlRequest */ 
       Set @Xmlvalue = SELECT X.R.value ('.','nvarchar (150)') 
        FROM @xmlRequest.nodes(XPATH) X(R) 
       if(@XmlValue = @value) 
       /*Add to result so i can return 
     /*I want to return all @xmlRequest if we has value from xpath*/    
END; 

Так что мой вопрос Если

Set @xmlRequest = SELECT xmlRequest FROM Api_request 
       WHERE Api_id = @Api_id 

Если мы получим несколько результат: это можно перебирать? Если да, насколько я могу это сделать?

Как вернуть несколько @xmlRequest как Api_id - это то же самое?

Кто-нибудь работает над таким сценарием? Пожалуйста, помогите мне.

+0

Является ли XML в вашей таблице уже введенным XML или это VARCHAR (запрос из-за '')? – Shnugo

+0

@Shnugo: Поле xmlRequest - тип VARCHAR. – Somu

+0

Почему вы хотите использовать хранимую процедуру, если вы делаете не что иное, как * чтение * данных? Используйте TVF или VIEW ... И далее: ваш пример не очищает, что вы ищете. Псевдокод даже не компилировался. Какие параметры вы проходите? – Shnugo

ответ

-1

Ваш вопрос не совсем ясно, но, пожалуйста, посмотрите на это:

CREATE TABLE #testTbl(Api_id INT, xmlRequest VARCHAR(MAX), SentTime DATETIME); 
INSERT INTO #testTbl VALUES 
(1,'<?xml version="1.0"?> 
<!DOCTYPE PARTS SYSTEM "parts.dtd"> 
<PARTS> 
    <TITLE>Computer Parts</TITLE> 
    <PART> 
     <ITEM>Motherboard</ITEM> 
     <MANUFACTURER>ASUS</MANUFACTURER> 
     <MODEL>P3B-F</MODEL> 
     <COST> 123.00</COST> 
    </PART> 
</PARTS>',GETDATE()) 
,(1,'<?xml version="1.0"?> 
<!DOCTYPE PARTS SYSTEM "parts.dtd"> 
<PARTS> 
    <TITLE>Computer Parts</TITLE> 
    <PART> 
     <ITEM>CPU</ITEM> 
     <MANUFACTURER>INTEL</MANUFACTURER> 
     <MODEL>CPUModelXY</MODEL> 
     <COST>345.00</COST> 
    </PART> 
</PARTS>',GETDATE()) 
,(2,'<?xml version="1.0"?> 
<!DOCTYPE PARTS SYSTEM "parts.dtd"> 
<PARTS> 
    <TITLE>Car Parts</TITLE> 
    <PART> 
     <ITEM>Wheel</ITEM> 
     <MANUFACTURER>Pirelli</MANUFACTURER> 
     <MODEL>WheelModelXY</MODEL> 
     <COST>100.00</COST> 
    </PART> 
</PARTS>',GETDATE()); 

Это rerturn все строки, где api_id = 1

SELECT Api_id 
     ,CONVERT(XML,xmlRequest,2) AS xmlRequest 
     ,SentTime 
FROM #testTbl 
WHERE Api_id=1; 

Это будет возвращать подобные таблице данные. Вы можете использовать "нормальный" SQL (WHERE, GROUP BY, ...), чтобы продолжить

DECLARE @Api_Id INT=NULL; 

WITH MyRequests AS 
(
    SELECT Api_id 
      ,RealXML.value('(/PARTS/TITLE)[1]','varchar(max)') AS Title 
      ,part.value('ITEM[1]','varchar(max)') AS Item 
      ,part.value('MANUFACTURER[1]','varchar(max)') AS Manufacturer 
      ,part.value('MODEL[1]','varchar(max)') AS Model 
      ,part.value('COST[1]','decimal(12,4)') AS Cost 
      ,SentTime 
    FROM #testTbl 
    CROSS APPLY(SELECT CONVERT(XML,xmlRequest,2) AS RealXML) AS ConvertedToXML 
    CROSS APPLY RealXML.nodes('/PARTS/PART') AS A(part) 
    WHERE @ApiId IS NULL OR [email protected]_Id 
) 
SELECT * 
FROM MyRequests 
--WHERE ... 
--GROUP BY ... 
--ORDER ... 
; 

Результат

+---+----------------+-------------+---------+--------------+----------+-------------------------+ 
| 1 | Computer Parts | Motherboard | ASUS | P3B-F  | 123.0000 | 2016-04-07 11:54:08.980 | 
+---+----------------+-------------+---------+--------------+----------+-------------------------+ 
| 1 | Computer Parts | CPU   | INTEL | CPUModelXY | 345.0000 | 2016-04-07 11:54:08.980 | 
+---+----------------+-------------+---------+--------------+----------+-------------------------+ 
| 2 | Car Parts  | Wheel  | Pirelli | WheelModelXY | 100.0000 | 2016-04-07 11:54:08.980 | 
+---+----------------+-------------+---------+--------------+----------+-------------------------+ 

Clean Up

GO 
DROP TABLE #testTbl; 
0

Попробуйте этот запрос

SELECT *,CONVERT(XML,xmlRequest,2) 
FROM Api_request 
WHERE Api_id = @Api_id 
    AND CONVERT(XML,xmlRequest,2).value('(/PARTS/PART/ITEM)[1]','nvarchar(max)') 
     LIKE '%'[email protected]+'%' 

Он вернет все xmlRequest, где conta ins your value

+0

OP упомянул в комментарии, что столбец xmlRequest имеет тип 'VARCHAR', вам не будет разрешено использовать' .value() 'there ... – Shnugo

+0

Тогда он может просто преобразовать эту строку в XML (т. Е. Cast (xmlRequest) как xml) .value ('(/ PARTS/PART/ITEM) [1]', 'nvarchar (max)') LIKE '% CPU%') –

+0

Просто попробуйте с исходными данными ;-) – Shnugo