我有一个具有XML输入参数的存储过程。我想在XML中使用空值,但是当我尝试使用OpenXML选择时,出现转换错误。
信息8114,第16级,状态5,第22行
将数据类型nvarchar转换为数字时出错。
IF (OBJECT_ID('tempdb..#Migracio') IS NOT NULL)
DROP TABLE #Migracio
CREATE TABLE #Migracio
(
Fee DECIMAL(16, 4) NULL,
Percentage DECIMAL(6, 3)
)
DECLARE @XML XML =
<Elelments xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Elelment>
<Fee xsi:nil="true"/>
<Percentage>50</Percentage>
</Elelment>
</Elelments>
DECLARE @h INT
EXEC sp_xml_preparedocument @h OUT, @XML
INSERT INTO [#Migracio] (Fee, Percentage)
SELECT Fee, Percentage FROM OPENXML(@h, '/Elelments/Elelment', 6)
WITH(Fee DECIMAL(16, 4), Percentage DECIMAL(6, 3))
EXEC sp_xml_removedocument @h
SELECT * FROM #Migracio
如何解决此问题?
答案 0 :(得分:1)
FROM OPENXML
以及用于打开和删除XML的存储过程已经过时了,不应再使用...而是使用XML数据类型提供的native XML-methods。
NULL
>
实际上并不需要使用带有xsi:nil
的{{1}}标记。缺少的元素被隐式地视为NULL
值。如果元素的存在是由架构或任何类型的规则强制执行的,则可以将其用于区分空字符串或NULL
。检查一下:
DECLARE @XML XML =
'<Elelments xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- your example -->
<Elelment>
<Fee xsi:nil="true" />
<Percentage>50</Percentage>
</Elelment>
<!-- both values are set -->
<Elelment>
<Fee>100</Fee>
<Percentage>50</Percentage>
</Elelment>
<!-- Fee is missing -->
<Elelment>
<Percentage>50</Percentage>
</Elelment>
</Elelments>';
-这将带回您想要的结果-无需担心NULL
值
SELECT e.value('(Fee/text())[1]','decimal(10,4)') AS Fee
,e.value('(Percentage/text())[1]','decimal(10,4)') AS Percentage
FROM @XML.nodes('/Elelments/Elelment') A(e);
-那么有什么区别?这将返回存在一个<Elelment>
节点的所有<Fee>
节点。您将获得两个节点。找不到丢失的<Elelment>
。
SELECT @XML.query('Elelments/Elelment[Fee]');
-通过此操作,您可以找到所有具有明确值<Fee>
的{{1}}
xsi:nil="true"
顺便说一句:您真的叫这个WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema-instance' AS xsi)
SELECT @XML.query('Elelments/Elelment[Fee/@xsi:nil="true"]');
吗?第二个“ L”莫名其妙地困扰着我...
答案 1 :(得分:0)
我想我可以用谷歌找到答案:
How to parse xml in sql server to process NULL value in DateTime DataType
“您需要做的就是忽略那些将导致为NULL值的属性。”
这是唯一的方法吗?