【发布时间】:2012-10-10 14:23:03
【问题描述】:
跟进来自:Is this XML format correct?
我有一些 SQL 代码在工作,循环通过 QABLOCK 并打印它们(在生产中 PRINT 将更改为 INSERT)。
-- XML instance
DECLARE @x1 XML
SELECT @x1 =
'
<tests>
<test id="1">
<qablock number="1">
<question>What is 1 + 1?</question>
<explanation>It"s 2.</explanation>
<options>
<option number="1" value="1" correct="0" />
<option number="2" value="2" correct="1" />
<option number="3" value="3" correct="0" />
<option number="4" value="4" correct="0" />
<option number="5" value="5" correct="0" />
</options>
</qablock>
<qablock number="2">
<question>What is 2 + 2?</question>
<explanation>It"s 4.</explanation>
<options>
<option number="1" value="1" correct="0" />
<option number="2" value="2" correct="0" />
<option number="3" value="3" correct="0" />
<option number="4" value="4" correct="1" />
<option number="5" value="5" correct="0" />
</options>
</qablock>
</test>
</tests>
'
DECLARE
@cnt INT,
@totCnt INT,
@child XML
-- counter variables
SELECT
@cnt = 1,
@totCnt = @x1.value('count(/tests/test/qablock)','INT')
-- loop
WHILE @cnt <= @totCnt BEGIN
SELECT
1 AS tests_id, --this is hard-coded
@cnt AS qablock_number,
@x1.value('(/tests/test/qablock[position()=sql:variable("@cnt")]/question/text())[1]','varchar(500)') AS question,
@x1.value('(/tests/test/qablock[position()=sql:variable("@cnt")]/explanation/text())[1]','varchar(1000)') AS explanation
PRINT 'Processing Child Element: ' + CAST(@cnt AS VARCHAR)
PRINT 'Child element: ' + CAST(@child AS VARCHAR(max))
PRINT ''
-- increment the counter variable
SELECT @cnt = @cnt + 1
END
我不知道这是否是正确的程序,但至少它似乎有效。我接下来想做的是运行另一个类似的脚本,该脚本循环遍历所有选项并打印它们。对于每个 OPTION,我需要打印:QABLOCK 编号、OPTION 编号、OPTION 值和 OPTION is_correct。我什至无法靠近。 :(这是我到目前为止所得到的:
-- XML instance
DECLARE @x1 XML
SELECT @x1 =
'
<tests>
<test id="1">
<qablock number="1">
<question>What is 1 + 1?</question>
<explanation>It"s 2.</explanation>
<options>
<option number="1" value="1" correct="0" />
<option number="2" value="2" correct="1" />
<option number="3" value="3" correct="0" />
<option number="4" value="4" correct="0" />
<option number="5" value="5" correct="0" />
</options>
</qablock>
<qablock number="2">
<question>What is 2 + 2?</question>
<explanation>It"s 4.</explanation>
<options>
<option number="1" value="1" correct="0" />
<option number="2" value="2" correct="0" />
<option number="3" value="3" correct="0" />
<option number="4" value="4" correct="1" />
<option number="5" value="5" correct="0" />
</options>
</qablock>
</test>
</tests>
'
DECLARE
@cnt INT,
@totCnt INT,
@child XML
-- counter variables
SELECT
@cnt = 1,
@totCnt = @x1.value('count(/tests/test/qablock/options/option)','INT')
-- loop
WHILE @cnt <= @totCnt BEGIN
SELECT
1 AS tests_id, --hard-coded value
@x1.value('(/tests/test/qablock/@number)[1]','varchar(500)') AS qablock_number,
@x1.value('(/tests/test/qablock/options/option[position()=sql:variable("@cnt")]/@number)[1]','varchar(500)') AS option_number
PRINT 'Processing Child Element: ' + CAST(@cnt AS VARCHAR)
PRINT 'Child element: ' + CAST(@child AS VARCHAR(max))
PRINT ''
-- increment the counter variable
SELECT @cnt = @cnt + 1
END
所以,显然它搞砸了,但我似乎无法弄清楚要改变什么。
首先,我不知道如何获取当前OPTION的父QABLOCK编号。
其次,只有我的前 5 个 option_number 正确显示了它们的数字,后 5 个显示为 NULL。
【问题讨论】:
-
嘿伙计——现在写一个完整的答案,但空值是因为你的计数从 1 到 10,而选项在 1-5 的两个块中(即 position() 重置为1 在第 6 个选项元素上)。快速修复是: (/tests/test/qablock/options/option/@number)[sql:variable("@cnt")]
-
非常感谢您的回复。上面的快速修复代码会在 SSMS 中生成错误:XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *' 所以将等待您的完整回复. :)
-
我什至不知道执行 WHILE 循环是否是正确的方法。这个网站似乎从不使用它们:link
标签: sql xml sql-server-2005 xquery