如何正确编写含空白节点的SPARQL Update语句更新RDF数据
SPARQL更新Bob体重值失败的解决方法
原RDF数据
@prefix : <http://example.org/-schema#> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . :Person a rdf:Class ; :hasAttribute :name,:weight. :Bob a :Person ; :hasAttribute [rdf:type :name; :hasValue 'Bob'], [rdf:type :height; :hasValue '1.67'^^xsd:decimal], [rdf:type :weight; :hasValue '70.2'^^xsd:decimal]. :John a :Person ; :hasAttribute [rdf:type :name; :hasValue 'John'], [rdf:type :height; :hasValue '1.71'^^xsd:decimal], [rdf:type :weight; :hasValue '70.2'^^xsd:decimal].
原SPARQL更新语句(存在问题)
DELETE { ?person :hasAttribute [ rdf:type :weight; :hasValue ?oldWeight ] . } INSERT { ?person :hasAttribute [ rdf:type :weight; :hasValue "71.8"^^xsd:decimal ] . } WHERE { ?person rdf:type :Person ; :hasAttribute [ rdf:type :name; :hasValue "Bob" ] . ?person :hasAttribute [ rdf:type :weight; :hasValue ?oldWeight ] . }
问题原因
原语句的DELETE部分用了匿名节点模式[rdf:type :weight; :hasValue ?oldWeight],但这个匿名节点和WHERE子句中匹配到的Bob的weight属性匿名节点没有绑定关系。SPARQL会把DELETE里的匿名节点当成独立模式,没法精准匹配要删除的三元组,结果只会新增新的weight属性,旧的属性节点还留在数据里。
修改后的SPARQL语句
DELETE { ?person :hasAttribute ?weightAttr . ?weightAttr rdf:type :weight ; :hasValue ?oldWeight . } INSERT { ?person :hasAttribute [ rdf:type :weight; :hasValue "71.8"^^xsd:decimal ] . } WHERE { ?person rdf:type :Person ; :hasAttribute [ rdf:type :name; :hasValue "Bob" ] ; :hasAttribute ?weightAttr . ?weightAttr rdf:type :weight ; :hasValue ?oldWeight . }
修改说明
- 在WHERE子句里,把Bob的weight属性节点绑定到变量
?weightAttr,明确匹配到要删除的具体属性节点 - DELETE部分直接引用
?weightAttr变量,精准删除该属性节点和Bob的关联,以及该节点的类型、旧值三元组 - INSERT部分保持不变,新增更新后的weight属性节点
这样就能彻底删除旧的weight属性,同时添加新值,完成正确更新。
内容的提问来源于stack exchange,提问作者lix joy
相关产品推荐
相关产品推荐

