T-SQL在XML中使用空值

时间:2018-09-17 19:58:53

标签: sql-server xml tsql

我有一个具有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

如何解决此问题?

2 个答案:

答案 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值的属性。”

这是唯一的方法吗?