SPARQL Update example for updating more than one triple in a single query

16,281

Solution 1

It's still not entirely clear to me what you're trying to achieve and why the example update that you give is not doing what you want, but if the aim is to have an update that replaces triples for a given subject, you could do something like this:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
@prefix ex: <http://example.org/> 

DELETE {?s ?p ?o}
INSERT {?s ex:title "foo" ;
           ex:description "bar" ;
           rdf:type ex:FooBar .  
       }
WHERE  { ?s ?p ?o . 
         FILTER (?s = ex:subject1) 
}

The above operation will delete all existing triples with ex:subject1 as the subject, and insert a new title, description, and type.

Or if you don't like filters, you can also formulate the above like this:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
@prefix ex: <http://example.org/> 

DELETE {ex:subject1 ?p ?o}
INSERT {ex:subject1 ex:title "foo" ;
                    ex:description "bar" ;
                    rdf:type ex:FooBar .  
}
WHERE  { 
        ex:subject1 ?p ?o . 
}

If you only want to delete specific properties for a given subject (rather than all triples with that subject), you can modify the operation like so:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
@prefix ex: <http://example.org/> 

DELETE {ex:subject1 ex:title ?t ;
                    ex:description ?d ; 
                    rdf:type ?c . 
       }
INSERT {ex:subject1 ex:title "foo" ;
                    ex:description "bar" ;
                    rdf:type ex:FooBar .  
}
WHERE  { 
        ex:subject1 ex:title ?t ;
                    ex:description ?d ;
                    rdf:type ?c . 
}

Solution 2

In SPARQL updates are represented as a DELETE followed by an INSERT:

http://www.w3.org/TR/2010/WD-sparql11-update-20100126/#t413

PREFIX foaf:  <http://xmlns.com/foaf/0.1/>

WITH <http://example/addresses>
DELETE { ?person foaf:firstName 'Bill' }
INSERT { ?person foaf:firstName 'William' }
WHERE
  { ?person a foaf:Person .
    ?person foaf:firstName 'Bill'
  }

Solution 3

Hallelujah thank God.

After 3 days hitting my head on the wall I believe I have the solution, which is like a work around. First you make the DELETE statement, then you use the semicolon to specify the triples you want to insert. Its still two operations, but at least they are controlled by the query server, i. e. you do not have to perform two separate requests, one for DELETE other for UPDATE (very dangerous).

Here is my working code, now (apparrently) fixed:

WITH GRAPH  <http://127.0.0.1:3000/dendro_graph>  
DELETE 
{ 
  :teste  dc:creator  ?o0 .
  :teste  dc:title    ?o1 .
} 
WHERE 
{ 
  :teste  dc:creator  ?o0 .
  :teste  dc:title    ?o1 .
}; 

<------NOTE THE SEMICOLON at the end of the first part

INSERT DATA
{ 
  :teste   dc:creator   "criador%20do%20teste"  .
  :teste   dc:creator   "second%20criador%20do%20teste"  .
  :teste   dc:creator   "third%20criador%20do%20teste"  .
  :teste   dc:creator   "fourth%20criador%20do%20teste"  .
  :teste   dc:title     "t1"  .
  :teste   dc:title     "t3"  .
  :teste   dc:title     "second%20title"  .
}
Share:
16,281
João Rocha da Silva
Author by

João Rocha da Silva

An Informatics Engineering PhD with a knack for classic car mechanics and spicy food. I love everything Web programming and database related! &lt;3 NodeJS, AngularJS, everything JS!

Updated on August 07, 2022

Comments

  • João Rocha da Silva
    João Rocha da Silva almost 2 years

    Can anyone point me to a valid UPDATE statement in SPARQL in any documentation (be it W3C, virtuoso, semantic web page, or your own custom code, etc?

    It has to be complete with WHERE specifications and more than one triple being updated in a single query.

    Thanks.

    EDIT / Example:

    Here is my current code, which has the goal of replacing all current values of dc:creator, dc:title and dc:description with the ones specified in the INSERT clause. Is this query correct, both in logic and syntax?

    WITH GRAPH  <http://127.0.0.1:3000/dendro_graph>  
    DELETE 
    { 
      :teste  dc:creator      ?o0 .
      :teste  dc:title        ?o1 .
      :teste  dc:description  ?o2 .
    }
    INSERT 
    { 
      :teste  dc:creator      "Creator%201" .
      :teste  dc:creator      "Creator%202" .
      :teste  dc:title        "Title%201" .
      :teste  dc:description  "Description%201" .
    } 
    WHERE 
    { 
      :teste  dc:creator      ?o0 .
      :teste  dc:title        ?o1 .
      :teste  dc:description  ?o2 .
    } 
    
  • João Rocha da Silva
    João Rocha da Silva over 10 years
    Thanks, I already read that documentation. I need a query capable of updating more than one triple in a single operation. In practice, deleting all triples matching the WHERE condition and replacing them with some others. Since I want to avoid having to know the old values of all the elements in the triple, I cannot use DELETE DATA or INSERT DATA statements; I need bindings in the query.
  • Jeen Broekstra
    Jeen Broekstra over 10 years
    You don't need separate operations for this (though there's nothing wrong with it in principle).
  • João Rocha da Silva
    João Rocha da Silva over 10 years
    If the system is used concurrently, the deletes and inserts may be performed in such an order that it may leave the database in inconsistent states. At least tjis way the server will handle the commits at the end of each couple of operation, even though there are no ACID transactions on Virtuoso as far as I know.
  • Jeen Broekstra
    Jeen Broekstra over 10 years
    You're missing my point. You can do this kind of update in a single SPARQL operation. You don't need to create a sequence of two or more operations, like you're doing here.
  • João Rocha da Silva
    João Rocha da Silva over 10 years
    Well that is what ive been trying to do for 3 days... All my google resulta for thr first 3 pages of the search are visited, so if you have a solution that does not require a sequence of operations I would love to hear it :-)
  • Jeen Broekstra
    Jeen Broekstra over 10 years
    The thing is that you give an example of such a solution yourself, in your question, and you're not explaining why that solution is not working for you. Nevertheless, I've tried to give you an alternative solution, see my answer.
  • João Rocha da Silva
    João Rocha da Silva over 10 years
    Thank you very much for taking the time to provide such a detailed example. I will run some queries in the Virtuoso interface to illustrate my need, and will test your suggestions. If they work for me, this will be the accepted answer.
  • Joshua Taylor
    Joshua Taylor about 8 years
    The whole SPARQL 1.1 Update specification describes how you insert, delete, etc., in SPARQL.
  • Oswin Noetzelmann
    Oswin Noetzelmann almost 7 years
    What Joshua says - See SPARQL 1.1
  • crapthings
    crapthings almost 4 years
    any possible to UPDATE ?Concept skosxl:prefLabel/skosxl:literalForm ?Label and there's might no skosxl:altLabel resource and its skosxl:literalForm, then UPDATE prefLabel's label and insert altLabel resource and skosxl:literalForm together?
  • Jigar Gajjar
    Jigar Gajjar over 2 years
    Will it do insert only operation if triples don't exists in db?
  • Jeen Broekstra
    Jeen Broekstra over 2 years
    @jigar-gajjar no, because if the triples don't exist, the WHERE clause won't match.