【问题标题】:Passing parameter to CosmosDB stored procedure将参数传递给 CosmosDB 存储过程
【发布时间】:2018-03-22 17:20:24
【问题描述】:

我有一个 Cosmos DB 存储过程,我在其中传递逗号分隔的 ID 列表。我需要将这些 ID 传递给查询。当我将一个值传递给参数时,它工作正常,但没有超过一个值。

如果有人可以在这里提供帮助,那就太好了。 下面是存储过程的代码:

function getData(ids) {
var context = getContext();
var coll = context.getCollection();
var link = coll.getSelfLink();
var response = context.getResponse();

var query =  {query: "SELECT * FROM c where c.vin IN (@ids)", parameters: 
[{name: "@ids", value: ids}]};


var requestOptions = {
                    pageSize: 500
    };

var run = coll.queryDocuments(link, query, requestOptions, callback);

function callback(err, docs) {
    if (err) throw err;
    if (!docs || !docs.length) response.setBody(null);
    else {
          response.setBody(JSON.stringify(docs));
        }
}

if (!run) throw new Error('Unable to retrieve the requested information.');
}

【问题讨论】:

  • 能否提供客户端代码,即在哪里执行存储过程?
  • @MichaelKoltachev 您也可以在门户网站上执行该过程。

标签: c# .net azure azure-cosmosdb


【解决方案1】:

对于数组,你应该使用ARRAY_CONTAINS函数:

var query =  {
    query: "SELECT * FROM c where ARRAY_CONTAINS(@ids, c.vin)", 
    parameters: [{name: "@ids", value: ids}]
};

另外,正如this doc 中所述,您的@ids 数组可能以字符串形式发送

在 Azure 门户中定义存储过程时,输入参数始终作为字符串发送到存储过程。即使您将字符串数组作为输入传递,该数组也会转换为字符串并发送到存储过程。为了解决这个问题,您可以在存储过程中定义一个函数来将字符串解析为数组

所以你可能需要在查询之前解析它:

function getData(ids) {
    arr = JSON.parse(ids);
}

相关:

How can I pass array as a sql query param for cosmos DB query

https://github.com/Azure/azure-cosmosdb-node/issues/156

【讨论】:

    【解决方案2】:

    你可以这样做:

    存储过程内部

    1. 使用 split 函数将一个参数解析为一个数组
    2. 遍历数组和
      a) 构建参数名称/值对,并将其推送到稍后查询使用的参数数组中
      b) 使用参数名称构建一个字符串,以便在 IN 语句的括号内使用
    3. 构建查询定义并将其传递给集合。

    示例

    这是参数值的样子:“abc,def,ghi,jkl” 如果您要使用它,请将“stringProperty”替换为您要查询的属性的名称。

    // SAMPLE STORED PROCEDURE
    function spArrayTest(arrayParameter) {
        var collection = getContext().getCollection();
        
        var stringArray = arrayParameter.split(",");
        var qParams = [];
        var qIn = "";
        for(var i=0; i<stringArray.length; i++){
            var nm = '@p'+ i; // parameter name
            qParams.push({name: nm, value: stringArray[i]});
            qIn += ( nm +','); // parameter name for query
        }
        qIn = qIn.substring(0,qIn.length-1); // remove last comma
    
        // qIn only contains a list of the names in qParams
        var qDef = 'SELECT * from documents d where d.stringProperty in ( ' + qIn + ' )';
    
        console.log(qParams[0].name);
        
        // Query Definition to be passed into "queryDocuments" function
        var q = {
            query: qDef,
            parameters: qParams
        };
    
        // Query documents
        var isAccepted = collection.queryDocuments(
            collection.getSelfLink(),
            q,
        function (err, feed, options) {
            if (err) throw err;
    
            // Check the feed and if empty, set the body to 'no docs found', 
            // else return all documents from feed
            if (!feed || !feed.length) {
                var response = getContext().getResponse();
                response.setBody('no docs found with an stringProperty in ' + arrayParameter);
            }
            else {
                var response = getContext().getResponse();            
                response.setBody(feed);
            }
        });
    
        if (!isAccepted) throw new Error('The query was not accepted by the server.');
    }
    

    【讨论】:

      【解决方案3】:

      请参考我的示例 js 代码,它适用于我。

      function sample(ids) {
          var collection = getContext().getCollection();
      
          var query = 'SELECT * FROM c where c.id IN ('+ ids   +')'
          console.log(query);
      
          var isAccepted = collection.queryDocuments(
              collection.getSelfLink(),
              query,
              function (err, feed, options) {
                  if (err) throw err;
                  if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
                  else {
                      for(var i = 0;i<feed.length;i++){
                          var doc = feed[i];
                          doc.name = 'a';
                          collection.replaceDocument(doc._self,doc,function(err) {
                                   if (err) throw err;
                       });
                      }
                      getContext().getResponse().setBody(JSON.stringify("success"));
                  }
              });
      
          if (!isAccepted) throw new Error('The query was not accepted by the server.');
      }
      

      参数:'1','2','3'

      希望对你有帮助。

      【讨论】:

      猜你喜欢
      • 2016-04-05
      • 1970-01-01
      • 2013-06-17
      • 2012-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多