我有一个如下所示的xml文件。具有主分支Teacherdetails的xml查询可以是单个对象或多个对象。内部教师详细信息学生人数用b表示,学生列表以嵌套对象的形式表示。
<teacherdetails>
<teacher>2222</teacher>
<a>10</a>
<b>3</b>
<students>
<student>
<stua>2000</stua>
<dista>1</dista>
</student>
<student>
<stua>20</stua>
<dista>1</dista>
</student>
<student>
<stua>20</stua>
<dista>1</dista>
</student>
<student>
<Reportno>1586215497241</Reportno>
<sal>
<month>13.245555</month>
<month>72.234355</month>
</sal>
</teacherdetails>
<teacherdetails>
<teacher>2222</teacher>
<a>10</a>
<b>3</b>
<students>
<student>
<stua>2000</stua>
<dista>1</dista>
</student>
<student>
<stua>20</stua>
<dista>1</dista>
</student>
<student>
<stua>20</stua>
<dista>1</dista>
</student>
<student>
<Reportno>1586215497241</Reportno>
<sal>
<month>13.245555</month>
<month>72.234355</month>
</sal>
</teacherdetails>
我正在尝试使用SQL访问a,b,b学生的详细信息。当我使用while循环使用xml.nodes
时,我尝试设置低于该值会引发错误
;with numbers as
(
select number
from master..spt_values
where type = 'P'
)
select
T.N.value('teacher[1]', 'varchar(50)') as teacher,
T.N.value('(students/student/stua[position()=sql:column("N.Number")])['+ @set +']', 'varchar(max)') as student,
T.N.value('(students/student/dista[position()=sql:column("N.Number")])['+ @set +']', 'varchar(max)')as distance
from
@string.nodes('/teacherdetails') as T(N)
cross join
numbers as n
where
n.number between 1 and (T.N.value('count(students)', 'int'))
注意:当我用硬编码1或2代替@set值时,它工作正常]
引发错误:
这里应该是字符串文字...
我尝试更改引号使其成为动态查询
declare @x xml = N'
<teacherdetails>
<teacher>2222</teacher>
<a>10</a>
<b>3</b>
<students>
<student>
<stua>2000</stua>
<dista>1</dista>
</student>
<student>
<stua>20</stua>
<dista>2</dista>
</student>
<student>
<stua>30</stua>
<dista>3</dista>
</student>
</students>
<Reportno>1586215497241</Reportno>
<sal>
<month>13.245555</month>
<month>72.234355</month>
</sal>
</teacherdetails>
<teacherdetails>
<teacher>3456</teacher>
<a>10</a>
<b>2</b>
<students>
<student>
<stua>789</stua>
<dista>1</dista>
</student>
<student>
<stua>20</stua>
<dista>2</dista>
</student>
</students>
<Reportno>1586215343434</Reportno>
<sal>
<month>13.245555</month>
<month>72.234355</month>
</sal>
</teacherdetails>
';
select
t.tchr.value('./teacher[1]', 'nvarchar(50)') as teacherId,
s.std.value('./stua[1]', 'nvarchar(50)') as stua,
s.std.value('./dista[1]', 'nvarchar(50)') as dista
from @x.nodes('./teacherdetails') as t(tchr) --teacher
cross apply t.tchr.nodes('./students/student') as s(std); --students of each teacher
--for your approach, student[position()= sql:column("n.number")]/stua is always a single element thus [1]
;with numbers as(
select number
from master..spt_values
where type = 'P'
)
select
n.number,
T.N.value('teacher[1]', 'varchar(50)') as teacher,
T.N.value('(./students/student[position()= sql:column("n.number")]/stua)[1]', 'varchar(max)') as student,
T.N.value('(./students/student[position()= sql:column("n.number")]/dista)[1]', 'varchar(max)')as distance
from @x.nodes('/teacherdetails') as T(N)
cross join numbers as n
where n.number between 1 and (T.N.value('./b[1]','int'));