2015-03-17 5 views
6

Esiste un modo per chiamare in modo ricorsivo le stored procedure (o anche le UDF se questo funzionerà) rispetto ai documenti DocumentDB?DocumentDB chiamata stored procedure da un'altra stored procedure o stessa

abbiamo un documento che sembra qualcosa di simile:

{ 
    "docID" : "my_id", 
    "owner" : "fred", 
    "items" : [ 
    { 
     "itemID" : "1", 
     "type" : "item", 
     "value" : 3 
    }, 
    { 
     "itemID" : "2", 
     "type" : "group", 
     "items" : [ 
     { 
      "itemID" : "2.1", 
      "type" : "group", 
      "items" : [ 
      { 
       "itemID" : "2.1.1", 
       "type" : "item", 
       "value" : 2 
      }, 
      { 
       "itemID" : "2.1.2", 
       "type" : "item", 
       "value" : 4 
      } 
      ] 
     }, 
     { 
      "itemID" : "2.2", 
      "type" : "item", 
      "value" : 1 
     } 
     ] 
    } 
    ] 
} 

Ogni volta che abbiamo "items", che "items" array può contenere le voci che sono un mix di "type" : "item" e "type" : "group". Le voci di "type" : "item" hanno un semplice campo "value" che deve essere sommato. Le voci che sono di "type" : "group" hanno una matrice "items" ... e così via. In teoria, non esiste un limite al livello di ricorsione, che riconosco sia un problema, ma in pratica i livelli raramente scendono sotto i 4 o 5 in profondità.

Pseudocodice per quello che sto cercando di scrivere simile a questa:

function sumValues(items) { 
    int total = 0; 
    forEach(item in items) { 
     if (item.type == "item") { 
      total += item.value; 
     } else { 
      total += sumValues(item.items); 
     } 
    } 
    return total; 
} 

function sumAllValues() { 
    var ctx = getContext(); 
    var coll = ctx.getCollection(); 
    var response = ctx.getResponse(); 

    // query for docs by owner 
    var filterQuery = 'SELECT * FROM Docs d where d.owner = \\\"fred\\\"'; 
    var done = coll.queryDocuments(coll.getSelfLink(), filterQuery, {}, 
    function (err, docs, options) { 
     if (err) throw new Error ('Error' + err.message); 

     var total = 0; 
     docs.forEach(function(doc) { 
     total += sumTotals(doc.items); 
     }); 

     response.setBody('Total: ' + total); 
    }); 
} 

Questo è anche possibile? DocumentDB supporta il richiamo di un sproc da un altro sproc? Può una chiamata sproc sé?

ho trovato un paio di DocumentDB memorizzati riferimenti procedura on-line, tra cui this e this e this e this più una miriade di altre pagine.

Se è possibile, penso che avrei potuto interrogare qualche modo la collezione per ottenere lo sProc che voglio chiamare, e quindi in qualche modo riferimento al sproc, invece di chiamare sumTotals() direttamente come si farebbe con un linguaggio autonomo.

Stiamo appena iniziando a guardare la programmazione con DocumentDB, quindi non siamo completamente sicuri di cosa possiamo ancora fare. Grazie per qualsiasi assistenza o consiglio.

+0

Potrei essere in grado di utilizzare qualcosa di [questo] (http://www.documentdb.com/javascript/tutorial#transactions) esempio che definisce una funzione 'swapItems' chiamata direttamente dalla funzione genitore. – shoover

+0

Vota [qui] (https://feedback.azure.com/forums/34192--general-feedback/suggestions/16267270-allow-to-use-udf-user-defined-function-inside-ad) da aggiungere questa opzione –

risposta

6

Penso che tu sia sulla strada giusta qui.

Non è possibile eseguire una procedura memorizzata da una procedura memorizzata.

Tuttavia, è possibile impostare all'interno di una stored procedure, che può essere referenziata, richiamata e riutilizzata all'interno di quella stored procedure.

In questo caso, è sufficiente definire la funzione sumValues() all'interno della procedura memorizzata genitore sumAllValues() (proprio come nell'esempio swapItems() menzionato).

function sumAllValues() { 
    var ctx = getContext(); 
    var coll = ctx.getCollection(); 
    var response = ctx.getResponse(); 

    // query for docs by owner 
    var filterQuery = 'SELECT * FROM Docs d where d.owner = \\\"fred\\\"'; 
    var done = coll.queryDocuments(coll.getSelfLink(), filterQuery, {}, 
     function (err, docs, options) { 
      if (err) throw new Error ('Error' + err.message); 

      var total = 0; 
      docs.forEach(function(doc) { 
       total += sumValues(doc.items); 
      }); 

      response.setBody('Total: ' + total); 
     }); 

    function sumValues(items) { 
     int total = 0; 
     items.forEach(function(item) { 
      if (item.type == "item") { 
       total += item.value; 
      } else { 
       total += sumValues(item.items); 
      } 
     }); 
     return total; 
    } 
} 

È anche possibile definire UDF per la logica che desideri condividere e riutilizzare in più le stored procedure e query.

+1

Questo suggerimento - spostando la definizione della funzione sumValues ​​all'interno della definizione sproc - ha funzionato per me, quindi ho aggiornato la risposta con l'esempio di codice e lo accetto. – shoover