Starting from version 5.0, Virtuoso supports SPARQL/Update extension of SPARQL. This is sufficient for most of routine data manipulation operations. If SPARQL_UPDATE role is granted to SPARQL user then data manipulation statements may be executed via SPARQL web service endpoint as well as data querying.
Two functions allow the user to alter RDF storage by inserting or deleting all triples listed in some vector. Both functions receive an IRI of a graph that should be altered and a vector of triples that should be added or removed. The graph IRI can be either IRI ID or a string. The third optional argument of these functions control transactional behavior: the value of parameter is passed to log_enable function. The return values of functions are not defined and should not be used by applications.
create function DB.DBA.RDF_INSERT_TRIPLES (in graph_iri any, in triples any, in log_mode integer := null)
create function DB.DBA.RDF_DELETE_TRIPLES (in graph_iri any, in triples any, in log_mode integer := null)
Simple operations may be faster if written as low-level SQL code instead of using SPARUL. E.g, the use of SPARQL DELETE is redundant when the application should delete from RDF_QUAD by using simple filters like:
delete from DB.DBA.RDF_QUAD
where G = DB.DBA.RDF_MAKE_IID_OF_QNAME (
'http://local.virt/DAV/sparql_demo/data/data-xml/source-simple2/source-data-01.rdf' );
On the other hand, simple filters does not work when search criteria refer to triples that are affected by the modification. Consider a function that deletes all triples whose subjects are nodes of type 'http://xmlns.com/foaf/0.1/Person'. Type information is stored in triples that will be deleted, so the simplest function is something like this:
create procedure DELETE_PERSONAL_DATA (in foaf_graph varchar)
{
declare pdata_dict, pdata_array any;
-- Step 1: select everything that should be deleted
pdata_dict := ((
sparql construct { ?s ?p ?o }
where { graph ?:foaf_graph {
?s ?p ?o . ?s rdf:type <http://xmlns.com/foaf/0.1/Person>
} }
));
-- Step 2: delete all found triples
pdata_array := dict_list_keys (pdata_dict, 1);
RDF_DELETE_TRIPLES (foaf_graph, pdata_array);
};
DELETE_PERSONAL_DATA (
'http://local.virt/DAV/sparql_demo/data/data-xml/source-simple2/source-data-01.rdf' );
Starting from Virtuoso 5.0, application may use SPARUL to do the same in a convenient way:
create procedure DELETE_PERSONAL_DATA (in foaf_graph varchar)
{
sparql delete { ?s ?p ?o }
where { graph ?:foaf_graph {
?s ?p ?o . ?s rdf:type <http://xmlns.com/foaf/0.1/Person>
} }
};
The graph where changes take place may be specified by an option in front of query, instead of being specified in 'insert into graph' clause.
sparql define input:default-graph-uri <A-Named-Graph>
insert { <http://myopenlink.net/dataspace/Kingsley#this>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
<http://rdfs.org/sioc/ns#User> };
The following two statements are equivalent but the latter may work faster, especially if there are many RDF views in the system or if some RDF views may contain triples for the graph in question. Note that neither of these two affect data that might come from RDF views.
sparql delete from graph <A-Named-Graph> { ?s ?p ?o } from <A-Named-Graph> where { ?s ?p ?o };
sparql clear graph <A-Named-Graph>;
Keywords 'insert in' and 'insert into' are interchangeable in Virtuoso for backward compatibility but SPARUL spec lists only 'insert into':
sparql insert into graph <A-Named-Graph> { <http://myopenlink.net/dataspace/Kingsley#this>
<http://rdfs.org/sioc/ns#id>
<Kingsley> };
sparql insert into graph <A-Named-Graph> { <http://myopenlink.net/dataspace/Caroline#this>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
<http://rdfs.org/sioc/ns#User> };
It is possible to use various expressions to calculate fields of new triples. This is very convenient, even if not a part of the original spec.
sparql insert into graph <A-Named-Graph> { ?s <http://rdfs.org/sioc/ns#id> `iri (bif:concat (str (?o), "Idehen"))` }
where { ?s <http://rdfs.org/sioc/ns#id> ?o };
'Modify graph' may be used as a sort of 'update' operation.
sparql modify graph <A-Named-Graph> delete { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?o } insert { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type1> ?o } where { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?o };
sparql delete from graph <A-Named-Graph> { <http://myopenlink.net/dataspace/Caroline#this> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type1> <http://rdfs.org/sioc/ns#User> };
The RDF information resource URI can be generated via a string expression.
sparql load bif:concat ("http://", bif:registry_get("URIQADefaultHost"), "/inputs/SparqlDawg/data-xml/Expr1/manifest.rdf")
into graph <A-Named-Graph>;
Number of operations can be sent to a web service endpoint as a single statement and executed in sequence.
sparql
insert in graph <A-Named-Graph> { <http://myopenlink.net/dataspace/Kingsley#this>
<http://rdfs.org/sioc/ns#id>
<Kingsley> }
insert into graph <A-Named-Graph> { <http://myopenlink.net/dataspace/Caroline#this>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
<http://rdfs.org/sioc/ns#User> }
insert into graph <A-Named-Graph> { ?s <http://rdfs.org/sioc/ns#id> `iri (bif:concat (str (?o), "Idehen"))` }
where { ?s <http://rdfs.org/sioc/ns#id> ?o };
modify graph <A-Named-Graph> delete { ?s <p2> ?o } insert { ?s <p2new> ?o } where { ?s <p2> ?o }
delete from graph <A-Named-Graph> { <http://myopenlink.net/dataspace/Caroline#this> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type1> <http://rdfs.org/sioc/ns#User> };
load bif:concat ("http://", bif:registry_get("URIQADefaultHost"), "/inputs/SparqlDawg/data-xml/Expr1/manifest.rdf") into graph <A-Named-Graph>
;
In case of huge RDF data ( for ex. 600 million triples ) loaded in the Virtuoso sever in a single graph, the fastest operation to drop the graph is:
sparql clear graph <graph-iri>;
The operation may be accelerated using log_enable (0) or even log_enable (2), with log_enable(1) after the operation.
Adding triples to graph
sparql
INSERT INTO GRAPH <http://BookStore.com>
{ <http://www.dajobe.org/foaf.rdf#i> <http://purl.org/dc/elements/1.1/title> "SPARQL and RDF" .
<http://www.dajobe.org/foaf.rdf#i> <http://purl.org/dc/elements/1.1/date> <1999-01-01T00:00:00>.
<http://www.w3.org/People/Berners-Lee/card#i> <http://purl.org/dc/elements/1.1/title> "Design notes" .
<http://www.w3.org/People/Berners-Lee/card#i> <http://purl.org/dc/elements/1.1/date> <2001-01-01T00:00:00>.
<http://www.w3.org/People/Connolly/#me> <http://purl.org/dc/elements/1.1/title> "Fundamentals of Compiler Design" .
<http://www.w3.org/People/Connolly/#me> <http://purl.org/dc/elements/1.1/date> <2002-01-01T00:00:00>. };
Adding triples to graph
A SPARQL/Update request that contains a triple to be deleted and a triple to be added (used here to correct a book title).
SPARQL
MODIFY GRAPH <http://BookStore.com>
DELETE
{ <http://www.w3.org/People/Connolly/#me> <http://purl.org/dc/elements/1.1/title> "Fundamentals of Compiler Design" }
INSERT
{ <http://www.w3.org/People/Connolly/#me> <http://purl.org/dc/elements/1.1/title> "Fundamentals" };
callret-0
VARCHAR
_______________________________________________________________________________
Modify <http://BookStore.com>, delete 1 and insert 1 triples -- done
1 Rows. -- 20 msec.
The example below has a request to delete all records of old books (with date before year 2000)
sparql
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
DELETE FROM GRAPH <http://BookStore.com> { ?book ?p ?v }
WHERE
{ GRAPH <http://BookStore.com>
{ ?book dc:date ?date
FILTER ( xsd:dateTime(?date) < xsd:dateTime("2000-01-01T00:00:00")).
?book ?p ?v.
}
};
_______________________________________________________________________________
Delete from <http://BookStore.com>, 6 triples -- done
1 Rows. -- 10 msec.
This snippet copies records from one named graph to another named graph based on a pattern:
sparql
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
INSERT INTO GRAPH <http://NewBookStore.com> { ?book ?p ?v }
WHERE
{ GRAPH <http://BookStore.com>
{ ?book dc:date ?date
FILTER ( xsd:dateTime(?date) > xsd:dateTime("2000-01-01T00:00:00")).
?book ?p ?v.
}
};
callret-0
VARCHAR
_______________________________________________________________________________
Insert into <http://NewBookStore.com>, 6 triples -- done
1 Rows. -- 30 msec.
An example to move records from one named graph to another named graph based on a pattern:
sparql
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
INSERT INTO GRAPH <http://NewBookStore.com>
{ ?book ?p ?v }
WHERE
{ GRAPH <http://BookStore.com>
{ ?book dc:date ?date .
FILTER ( xsd:dateTime(?date) > xsd:dateTime("2000-01-01T00:00:00")).
?book ?p ?v.
}
};
_______________________________________________________________________________
Insert into <http://NewBookStore.com>, 6 triples -- done
1 Rows. -- 10 msec.
sparql
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
DELETE FROM GRAPH <http://BookStore.com>
{ ?book ?p ?v }
WHERE
{ GRAPH <http://BookStore.com>
{ ?book dc:date ?date .
FILTER ( xsd:dateTime(?date) > xsd:dateTime("2000-01-01T00:00:00")).
?book ?p ?v.
}
};
_______________________________________________________________________________
Delete from <http://BookStore.com>, 3 triples -- done
1 Rows. -- 10 msec.
|
Previous
RDF and SPARQL API and SQL |
Chapter Contents |
Next
RDF Insert Methods in Virtuoso |