从SQL服务器的XML列中指定WHERE子句的SELECT值

时间:2017-08-15 14:29:08

标签: sql-server xml search where-clause

我有一个类似于此的SQL表:

create table #Temp_xml
(
ID int not null,
Name varchar(10) null,
Step XML null
)
truncate table #Temp_xml
Insert INTO #Temp_xml (ID, Name, Step) Values
(1, 'Query 1',
'<LoadData>
  <Step>
    <StepName>Step 1</StepName>
    <StepType>Validation</StepType>
    <Result>PAST</Result>
  </Step>
  <Step>
    <StepName>Step 2</StepName>
    <Command>SELECT colA, colB FROM Mytbl</Command>
    <ID>888</ID>
  </Step>
  <Step>
    <StepName>Step 3</StepName>
    <Command>Truncate table tblABC</Command>
    <ID>103</ID>
   </Step>
 </LoadData>')


 Insert INTO #Temp_xml (ID, Name, Step) Values
(2, 'Query 2',
'<LoadData>
  <Step>
    <StepName>Step 1</StepName>
    <StepType>Validation</StepType>
    <Result>True</Result>
    <ID>112</ID>
  </Step>
  <Step>
    <StepName>Step 2</StepName>
    <Command>SELECT colA, colB FROM Mytbl</Command>
  </Step>
  <Step>
    <StepName>Step 3</StepName>
    <Command>Exec dbo.MyStoredproc</Command>
   </Step>
 </LoadData>')
 Insert INTO #Temp_xml (ID, Name, Step) Values
(3, 'Query 3',
'<LoadData>
  <Step>
    <StepName>Step 1</StepName>
    <StepType>Validation</StepType>
    <Result>False</Result>
  </Step>
  <Step>
    <StepName>Step 2</StepName>
    <Command>SELECT colA, colB FROM Mytbl</Command>
    <ID>666</ID>
  </Step>
  <Step>
    <StepName>Step 3</StepName>
    <Command>Update tblXyz set colA = ''999'' FROM tbl_test</Command>
  </Step>
  <Step>
    <StepName>Step 4</StepName>
    <Command>Truncate table tblABC</Command>
    <ID>678</ID>
   </Step>
 </LoadData>')

我需要从#temp_xml中搜索列Step,其中ID = 678的行。以下查询将不会返回数据  有多个节点。

  select * from #Temp_xml
 WHERE step.value('(/LoadData/Step/ID)[1]', 'varchar(max)') = 678 

但是,由于第二次出现ID,我得到了预期的结果:

 select * from #Temp_xml
 WHERE step.value('(/LoadData/Step/ID)[2]', 'varchar(max)') = 678 

我的问题是,如何使这种搜索更通用,这样我就不必把它出现了  方括号[]?

1 个答案:

答案 0 :(得分:1)

您可以将.exist(...)函数与XPath查询一起使用。

SELECT * 
FROM #Temp_xml
WHERE step.exist('/LoadData/Step[ID="678"]') = 1

...如果您需要将变量传递给查询,您可以这样做......

DECLARE @id INT = 678;    
SELECT *
FROM #Temp_xml
WHERE step.exist('/LoadData/Step[ID=sql:variable("@id")]') = 1;