J'ai une application qui stocke divers points de données définis par l'utilisateur sur un enregistrement dans une colonne XML. Je n'ai aucun contrôle sur la façon dont ceux-ci sont stockés ou mis à jour.
Lorsque je recherche une colonne, elle peut renvoyer 1 valeur sur 3:
$ 64 question Je voudrais retourner ces chaînes vides en tant que null en utilisant xpath.
J'ai trouvé beaucoup de réponses sur le retour du null comme une piqûre vide mais rien de cette façon.
Ils finissent de cette façon lorsque quelqu'un a supprimé la valeur et au lieu de supprimer la balise, il la vide en <value />
tag. Les valeurs NULL se produisent lorsque la valeur n'a jamais été définie. Ils n'ont pas inclus xsi: nil.
Je l'ai fait avec une déclaration de cas:
select
so.SalesOrderId,
Case
when sopc.value('(Value)[1]','smalldatetime') IS null then Null
when sopc.value('(Value)[1]','smalldatetime') ='' then Null
Else sopc.value('(Value)[1]','smalldatetime')
End as sopc
From
SalesOrders so
Outer apply so.CustomColumns.nodes('/CustomColumnsCollection/CustomColumn[Name="ProjCompleted"]') sopc(sopc)
mais cela semble inefficace et ce n'est pas la seule colonne donc cela rend le code long et plus difficile à maintenir.
Modifier pour inclure des exemples de données
SalesOrderId CustomColumns
SO 1 "<CustomColumnsCollection>
<CustomColumn>
<Name>ProjCompleted</Name>
<DataType>1</DataType>
<Value />
</CustomColumn>
</CustomColumnsCollection>"
SO 2 "<CustomColumnsCollection>
<CustomColumn>
<Name>ProjCompleted</Name>
<DataType>1</DataType>
<Value>'2017-11-21'</Value>
</CustomColumn>
</CustomColumnsCollection>"
SO 3 "<CustomColumnsCollection>
</CustomColumnsCollection>"
**Output**
Current Desired
'' null
2017-11-21 2017-11-21
null null
Merci d'avance.
Spécifiez le nœud text()
dans l'élément Value
. Ce nœud est manquant lorsque vous avez une balise vide.
Essaye ça:
declare @X xml;
set @X = '<Value/>';
select @X.value('(Value/text())[1]', 'smalldatetime'),
@X.value('(Value/text())[1]', 'varchar(max)'),
@X.value('(Value/text())[1]', 'int'),
@X.value('(Value)[1]', 'smalldatetime'),
@X.value('(Value)[1]', 'varchar(max)'),
@X.value('(Value)[1]', 'int');
Résultat:
------------------- ---------- ----------- ----------------------- ---------- -----------
NULL NULL NULL 1900-01-01 00:00:00 0
C'est une bonne chose en général de toujours spécifier le noeud text()
. Le plan de requête est plus simple et plus efficace.