我正在尝试使用sql:variable
从XML文件中读取数据。我的问题是,我可以读取XML的第一行或第n行(或节点),但是我不能在行(或节点)中进行迭代。这是我使用sql:variable
:
CAST((SELECT @xmlExpenseItems.value(N'(/ExpenseItem//ExpenseID/node())[sql:variable("@iteratorVarChar")]','int')) AS int),
CAST((SELECT @xmlExpenseItems.value(N'(/ExpenseItem//ExpenseTypeID/node())[sql:variable("@iteratorVarChar")]','int')) AS int),
CAST((SELECT @xmlExpenseItems.value(N'(/ExpenseItem//ExpenseAmount/node())[sql:variable("@iteratorVarChar")]','float')) AS float)
其中@iteratorVarChar
是从int转换的varchar。
我收到错误“XQuery [value()]:仅”http://www.w3.org/2001/XMLSchema#decimal?“,”http://www.w3.org/2001/XMLSchema#boolean?“或'node()*'表达式作为谓词,在上面的代码的第一行找到'xs:string?'“。
当我用@ @iterator
切换@iteratorVarChar时已经是一个int,我得到“XQuery [value()]:'value()'需要一个单例(或空序列),找到类型为'xdt的操作数:untypedAtomic *'“
正如我所说,当我用sql:variable("@iteratorVarChar")
之类的int替换1
时,代码将与xml的第一个节点一起使用。
我的问题是,我错过了什么,还是我犯了根本错误?如何使这项工作?
我的整个代码如下(我注释了CREATE
以避免重新创建错误):
DECLARE @xmlExpenseItems XML
SET @xmlExpenseItems = '
<ExpenseItem>
<ExpenseID>5</ExpenseID>
<ExpenseTypeID>5</ExpenseTypeID>
<ExpenseAmount>5</ExpenseAmount>
</ExpenseItem>
<ExpenseItem>
<ExpenseID>3</ExpenseID>
<ExpenseTypeID>5</ExpenseTypeID>
<ExpenseAmount>7</ExpenseAmount>
</ExpenseItem>
'
--CREATE TABLE #ExpenseItems
--(ExpenseItemID int not null identity(1,1),
--ExpenseID int not null,
--ExpenseTypeID int not null,
--ExpenseAmount float not null
--)
DECLARE @iterator int = 1
DECLARE @IDCount int
SELECT @IDCount = (SELECT @xmlExpenseItems.value('count(/ExpenseItem)', 'int') )
DECLARE @iteratorVarChar varchar(3)
WHILE @iterator <= @IDCount
BEGIN
SET @iteratorVarChar = CAST(@iterator AS varchar(3))
INSERT INTO #ExpenseItems
(ExpenseID, ExpenseTypeID, ExpenseAmount)
VALUES
(
CAST((SELECT @xmlExpenseItems.value(N'(/ExpenseItem//ExpenseID/node())[sql:variable("@iteratorVarChar")]','int')) AS int),
CAST((SELECT @xmlExpenseItems.value(N'(/ExpenseItem//ExpenseTypeID/node())[sql:variable("@iteratorVarChar")]','int')) AS int),
CAST((SELECT @xmlExpenseItems.value(N'(/ExpenseItem//ExpenseAmount/node())[sql:variable("@iteratorVarChar")]','float')) AS float)
)
SET @iterator = @iterator + 1
END
select * from #ExpenseItems
答案 0 :(得分:1)
尝试基于集合的方法而不是迭代。 nodes()
函数从XML文档返回行集:
insert #ExpenseItems
(ExpenseID, ExpenseTypeID, ExpenseAmount)
select col.value('ExpenseID[1]', 'int')
, col.value('ExpenseTypeID[1]', 'int')
, col.value('ExpenseAmount[1]', 'int')
from @xmlExpenseItems.nodes('/ExpenseItem') doc(col)