xquerybasex

How to write a sequence of XQuery function calls?


I have a lot of such assignment statements let $tmp :=, because otherwise I get the error message "Incomplete FLOWR Expression, expecting return":

declare function module:import($xmlsrc as xs:string, $conn as xs:anyURI) {

  let $root := module:getXml($xmlsrc)
  
  (: Table01 :)

  let $id := 2
  
  let $tmp := trace("Table01")
  
  let $sqlstmt := "insert into Table01 (rel1,rel2,rel3,rel4,rel5) values(" 
       || $id || ", 
    '" || $root//myns:ftr[@n='abc']/myns:ftr[@type='p1'] || "', 
    '" || $root//myns:ftr[@n='abc']/myns:ftr[@type='p2'] || "', 
    '" || $root//myns:ftr[@n='abc']/myns:ftr[@type='p3'] || "', 
    '" || $root//myns:ftr[@n='abc']/myns:ftr[@type='p4'] || "')"
               
  let $tmp := sql:execute($conn, $sqlstmt)
       
  (: Table02 :)

  let $id := 3
  
  let $sqlstmt := "insert into Table02 (rel1,rel2,rel3,rel4,rel5) values(" 
       || $id || ", 
    '" || $root//myns:div[@n='abc']/myns:xyz[@type='p5'] || "', 
    '" || $root//myns:div[@n='abc']/myns:xyz[@type='p6'] || "', 
    '" || $root//myns:div[@n='abc']/myns:xyz[@type='p7'] || "', 
    '" || $root//myns:div[@n='abc']/myns:xyz[@type='p8'] || "')"
               
  let $tmp := sql:execute($conn, $sqlstmt)

  (: more tables to import to :)
    
    return()
};

Is there another way, i.e. without those assignment statements, to meet the XQuery requirements?


Solution

  • It looks as if you want a function that is called only for its side effects, and you don't actually want to return anything from the function.

    Functions with side-effects aren't well supported by the XQuery language specification, and you're very much in "vendor extensions" territory. So the answer is going to depend on which XQuery implementation you are using.

    You can call the functions without binding the results to variables, for example

    declare function (...) {
        module:getXml($xmlsrc),
        trace("Table01"),
        sql:execute($conn, "insert into Table02 (rel1,rel2,rel3,rel4,rel5) values(" 
           || $id || ", 
        '" || $root//myns:div[@n='abc']/myns:xyz[@type='p5'] || "', 
        '" || $root//myns:div[@n='abc']/myns:xyz[@type='p6'] || "', 
        '" || $root//myns:div[@n='abc']/myns:xyz[@type='p7'] || "', 
        '" || $root//myns:div[@n='abc']/myns:xyz[@type='p8'] || "')"),
        sql:execute($conn, "insert into Table02 (rel1,rel2,rel3,rel4,rel5) values(" 
           || $id || ", 
        '" || $root//myns:div[@n='abc']/myns:xyz[@type='p5'] || "', 
        '" || $root//myns:div[@n='abc']/myns:xyz[@type='p6'] || "', 
        '" || $root//myns:div[@n='abc']/myns:xyz[@type='p7'] || "', 
        '" || $root//myns:div[@n='abc']/myns:xyz[@type='p8'] || "')")
    };
    

    With both formulations the language spec offers no guarantee about order of execution, which is rather critical in a case like this; for such guarantees you will need to turn to vendor documentation.