9 Replies Latest reply: Jul 19, 2013 7:11 AM by martani RSS

    Bind Variables in SPARQL Queries

    martani

      Hi,

       

      I am interested in bind variables and their use between queries, however while I see the concept behind the example given in the documentation (http://docs.oracle.com/cd/E11882_01/appdev.112/e25609/sem_jena.htm#autoId15) I am not able to grasp how to exactly pass the results of a query_1 for an ?x variable to another query query_2.

       

      Would it be possible to offer a more detailed explanation and a working simple code about how to do this using Jena Adapater.

       

      Thank you.

        • 1. Re: Bind Variables in SPARQL Queries
          alwu-Oracle

          Sorry for the late response. Was tied up with a deadline.

           

          Here is a complete example.

           

          1) Assume a model with the following triples

          % cat tests/forum2550843.nt

          <urn:s> <urn:related> <urn:A> .

          <urn:s> <urn:related> <urn:B> .

          <urn:y>  <urn:friendOf> <urn:x> .

          <urn:c> <urn:related> <urn:x> .

          <urn:d> <urn:related> <urn:x> .

           

           

          2) Run the following query to get the bind values and their internal resource IDs

          % cat ./tests/forum2550843.sparql1

          PREFIX oext: <http://oracle.com/semtech/jena-adaptor/ext/function#>

          select ?x  (oext:build-uri-for-id(?x) as ?xid)

          where { ?y  <urn:friendOf> ?x }

           

          The following is a possible answer to the above query.

          soln ( ?xid = <rdfvid:6354524810780932050> ) ( ?x = <urn:x> )

           

           

          3) Say we want to push the bind values of ?x from the above query into

          "SELECT ?subject ?x WHERE {  ?subject <urn:related>  ?x } "

           

          We can construct and run the following query:

          % cat ./tests/forum2550843.sparql2

          PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#no_fall_back>

          PREFIX ORACLE_SEM_UEAP_NS: <http://oracle.com/semtech#x$RDFVID%20in(?)>

          PREFIX ORACLE_SEM_UEPJ_NS: <http://oracle.com/semtech#x$RDFVID>

          PREFIX ORACLE_SEM_UEBV_NS: <http://oracle.com/semtech#6354524810780932050>

          SELECT ?subject ?x

          WHERE {

            ?subject <urn:related>  ?x

          }

           

          The following are the answers:

          soln ( ?x = <urn:x> ) ( ?subject = <urn:c> )

          soln ( ?x = <urn:x> ) ( ?subject = <urn:d> )

           

          Hope it helps,

           

          Zhe Wu

          • 2. Re: Bind Variables in SPARQL Queries
            martani

            Hi,

            Thank you for your reply, I can now make it work, and it is really of great usefulness to us to be able to bind variables on the fly like this.

             

            I have two questions however:

             

            1. Is it possible to bind multiple variables instead of only one?

             

            For example, in the request:

            SELECT ?subject ?x
              WHERE {
                   ?subject      <urn:related>      ?x .
                   ?subject      vcard:postal-code      ?p .
              }
              AND      ?x$RDFVID      in      (1,2,3);
            
            

             

            is it possible to bind ?p along with ?x so that we have something like this:

             

            SELECT ?subject ?x
              WHERE {
                   ?subject      <urn:related>      ?x .
                   ?subject      vcard:postal-code      ?p .
              }
              AND      ?x$RDFVID      in      (1,2,3);
              AND      ?p$RDFVID     in      (11,22,33);
            
            

             

            2. Is it possible to use this way of binding in SPARQL 1.1 Update queries ?

             

            I would also like to report a strange behavior we are experiencing with some of our queries: once a query has the keyword 'MINUS' or a 'BIND' which contains any operations on variables (possibly other keywords apply too), the function oext:build-uri-for-id() does not return any results. When checking the issued SQL or SEM_MATCH call, no projection of varname$RDFVID is made.

            Is this an intended behavior or there are some parameters to pass to the query we are missing?

             

            Example of queries where oext:build-uri-for-id() returns empty results:

             

            SELECT      ?s      (oext:build-uri-for-id(?s) as ?sid)      ?ss      WHERE
            {
                ?s    vcard:postal-code    "1234" .
                ?s    ?p    ?o .
                BIND( CONCAT(?o, " TEST")      as      ?ss)          
            }
            
            

             

            SELECT      ?s      (oext:build-uri-for-id(?s) as ?sid)      WHERE
            {
                ?s    vcard:postal-code    "1234" .
                ?s    ?p    ?o .
                MINUS { }          
            }
            
            

             

            Regards.

            Martani.

            • 3. Re: Bind Variables in SPARQL Queries
              alwu-Oracle

              Hi,

               

              Yes. You can bind multiple variables by URL encoding

               

              1) the following in ORACLE_SEM_UEAP_NS

              x$RDFVID in (?,?,?)  and p$RDFVID in (?,?,?)

               

              2) the following in ORACLE_SEM_UEPJ_NS

              x$RDFVID,p$RDFVID

               

              3) the following in ORACLE_SEM_UEBV_NS

              1,2,3,11,22,33

               

              This kind of bind variable/value setting should work for UPDATE as well.

               

              Hope it helps,


              Zhe Wu

              • 4. Re: Bind Variables in SPARQL Queries
                martani

                Hi,

                 

                This way of binding does not seem to be working for SPARQL update queries. I can see the SQL generated for the 'WHERE' part of the query, but there is no restriction on the variables I want to bind in this generated SQL.

                 

                Following is my query. If I run this on a select query, I get the binding correctly.

                 

                PREFIX    ORACLE_SEM_UEAP_NS:    <http://oracle.com/semtech#node$_SUFFIX%20LIKE%20(?)>
                PREFIX    ORACLE_SEM_UEPJ_NS:    <http://oracle.com/semtech#node$_SUFFIX>
                PREFIX    ORACLE_SEM_UEBV_NS:    <http://oracle.com/semtech#%25PATTERN%25>
                
                INSERT {
                    abc:JENA_GRAPH   graph:hasNode   ?node .
                }
                WHERE
                {
                    ?node     ndl:hasDevice     ?device .
                    ?device   ndl:deviceClass   ndl:SOME_TYPE .
                }
                
                

                 

                Can you provide a working example of how to do binding within update queries?

                 

                Thanks.

                • 5. Re: Bind Variables in SPARQL Queries
                  alwu-Oracle

                  Hi,

                   

                  How are you running the SPARQL Updates? Do you run this through Java APIs or through a SPARQL endpoint?

                   

                  Thanks,


                  Zhe

                  • 6. Re: Bind Variables in SPARQL Queries
                    martani

                    Hi,

                    I am using the Java API to run SPARQL update queries, this is an example of what I am trying to achieve :

                     

                    public static void runTestUpdateBinding() throws SQLException {
                        String[] modelNames = new String[] { };
                        String[] rulebases = new String[] { };
                    
                    
                    
                        OracleDataSource ods = new OracleDataSource();
                        ods.setURL("ORACLE CONNECTION STRING");
                        OracleConnection oc = (OracleConnection)ods.getConnection();
                        Oracle oracle = new Oracle(oc);
                    
                    
                    
                        Attachment attachment =
                            Attachment.createInstance(modelNames, rulebases, InferenceMaintenanceMode.NO_UPDATE, QueryOptions.ALLOW_QUERY_INVALID_AND_DUP);
                    
                    
                    
                        GraphOracleSem graph = new GraphOracleSem(oracle, "in_oracle", attachment, true);
                        ModelOracleSem model = new ModelOracleSem(graph);
                    
                       
                        //Insert few triples
                        String updateQuery = "INSERT DATA {                                        " +
                                             "  <http://sub/a>  <http://pred/a>  <http://obj/a> .\n" +
                                             "  <http://sub/b>  <http://pred/b>  <http://obj/b> .\n" +
                                             "  <http://sub/c>  <http://pred/c>  <http://obj/c>    " + 
                                             "}";
                        UpdateAction.parseExecute(updateQuery, model);
                    
                       
                        //Run the update query
                        updateQuery = "PREFIX    ORACLE_SEM_UEAP_NS:    <http://oracle.com/semtech#s$RDFVID%20IN(ORACLE_ORARDF_RES2VID(?),ORACLE_ORARDF_RES2VID(?))> \n" +
                                      "PREFIX    ORACLE_SEM_UEPJ_NS:    <http://oracle.com/semtech#s$RDFVID> \n" +
                                      "PREFIX    ORACLE_SEM_UEBV_NS:    <http://oracle.com/semtech#http%3A%2F%2Fsub%2Fa,http%3A%2F%2Fsub%2Fc> \n" +
                                     
                                      "INSERT { <http://sub/UPDATED_SUBJECT>    ?p    ?o } \n" +
                                      "WHERE  { ?s    ?p    ?o }";
                        UpdateAction.parseExecute(updateQuery, model);
                    
                       
                        model.close();
                    }
                    
                    

                     

                    Basically, I am expecting only "<http://sub/a>  <http://pred/a>  <http://obj/a>" and "<http://sub/c>  <http://pred/c>  <http://obj/c>" to match, however, "<http://sub/b>  <http://pred/b>  <http://obj/b>" also matches as you can see from the following results

                     

                    -------------------------------------------------------------------

                    | s                            | p               | o              |

                    ===================================================================

                    | <http://sub/c>               | <http://pred/c> | <http://obj/c> |

                    | <http://sub/UPDATED_SUBJECT> | <http://pred/c> | <http://obj/c> |

                    | <http://sub/b>               | <http://pred/b> | <http://obj/b> |

                    | <http://sub/UPDATED_SUBJECT> | <http://pred/b> | <http://obj/b> |

                    | <http://sub/a>               | <http://pred/a> | <http://obj/a> |

                    | <http://sub/UPDATED_SUBJECT> | <http://pred/a> | <http://obj/a> |

                    -------------------------------------------------------------------

                     

                    Also, in the underlying generated SQL, there is no restriction on s$RDFVID as in SELECT queries (i.e: ...where (s$RDFVID IN(ORACLE_ORARDF_RES2VID(?),ORACLE_ORARDF_RES2VID(?))) )

                    • 7. Re: Bind Variables in SPARQL Queries
                      alwu-Oracle

                      Hi Martani,

                       

                      When ARQ (2.8.8) gets an update request with a where clause, it will create a query. The namespace definition is omitted in the generated query. We have put in a fix for one of our customers. Please file an SR with Oracle support.

                       

                      Thanks,


                      Zhe Wu

                      • 8. Re: Bind Variables in SPARQL Queries
                        alwu-Oracle

                        BTW, with the updated arq-2.8.8.jar, this is the output (of a {?s ?p ?o} query) after the UPDATE.

                         

                        -------------------------------------------------------------------

                        | s                            | p               | o              |

                        ===================================================================

                        | <http://sub/c>               | <http://pred/c> | <http://obj/c> |

                        | <http://sub/UPDATED_SUBJECT> | <http://pred/c> | <http://obj/c> |

                        | <http://sub/b>               | <http://pred/b> | <http://obj/b> |

                        | <http://sub/a>               | <http://pred/a> | <http://obj/a> |

                        | <http://sub/UPDATED_SUBJECT> | <http://pred/a> | <http://obj/a> |

                        -------------------------------------------------------------------

                        • 9. Re: Bind Variables in SPARQL Queries
                          martani

                          Hi,

                           

                          Thank you, the updated arq-2.8.8.jar fixes the problem.

                           

                          Regards