如何在DocumentDB中执行现有的存储过程?

时间:2014-09-11 14:49:37

标签: azure stored-procedures azure-cosmosdb

我想在DocumentDB中创建一个存储过程,并在以后需要时使用它。要执行存储过程,我需要知道storedProcedureLink。当我使用CreateStoredProcedureAsync方法注册存储过程时,我得到了链接,如果我想稍后执行此存储过程,我应该自己存储此链接吗?如果我所知道的是程序名称,我可以执行存储过程吗?从所有的例子中我发现我需要在需要执行它之前创建并注册存储过程,是不是这样呢?

5 个答案:

答案 0 :(得分:5)

您可以预先创建存储过程并将其保存在服务器上以备将来使用。您不需要在使用它之前创建它。这仅用于示例目的。我们希望大多数时候存储过程已经存在,您只需在应用程序中使用它们。

您确实需要SelfLink来执行存储过程。 获得此功能的一种方法是查询存储过程(按名称),获取SelfLink,然后使用它来执行存储过程。

按名称查询存储过程看起来像;

StoredProcedure sproc = client.CreateStoredProcedureQuery(collection.StoredProceduresLink, "select * from root r where r.id = \"sproc name\"");

生成的sproc变量将包含要执行的存储过程的SelfLink。

var result = client.ExecuteStoredProcedureAsync(sproc.SelfLink);

有关如何使用存储过程的综合示例,请参阅发布的示例中的DocumentDB.Samples.ServerSideScripts项目; http://code.msdn.microsoft.com/Azure-DocumentDB-NET-Code-6b3da8af

答案 1 :(得分:2)

  

从所有的例子中我发现我需要在需要执行它之前创建并注册存储过程,是不是这样呢?

没有。存储过程创建和注册不必在执行期间发生。

样本具有教育意义,但不提供真实世界的模式。请参阅DocumentManagement basic CRUD operations。样本也假设一个集合。请参阅Partitioning basic CRUD operations

虽然我赞扬了DocumentDB对SQL编码约定的适应性,但对于.NET开发人员来说,当前的使用模式不足。在SQL Server中创建CRUD存储过程然后通过ADO.NET或DataSet中的TableAdapter按名称调用它们的十年旧模式在DocumentDB中不起作用。

  

如果我所知道的只是一个程序名,我可以执行存储过程吗?

是的,但它并不漂亮:

StoredProcedure storedProcedure = this.DocumentClient.CreateStoredProcedureQuery(new Uri(collection.StoredProceduresLink)).Where(p => p.Id == "GetPunkRocker").AsEnumerable().FirstOrDefault();

使用PartitionResolver时,事情会变得更复杂:

    public async Task<PunkRocker> GetPunkRockerAsync(string partitionKey)
    {
        foreach (string collectionLink in this.PartitionResolver.ResolveForRead(partitionKey))
        {
            DocumentCollection collection = this.DocumentClient.CreateDocumentCollectionQuery(new Uri(this.Database.SelfLink)).Where(c => c.SelfLink == collectionLink).AsEnumerable().FirstOrDefault();

            if (collection == null)
            {
                // Log...
                continue;
            }

            StoredProcedure storedProcedure = this.DocumentClient.CreateStoredProcedureQuery(new Uri(collection.StoredProceduresLink)).Where(p => p.Id == "GetPunkRocker").AsEnumerable().FirstOrDefault();

            if (storedProcedure == null)
            {
                // Log...
                continue;
            }

            PunkRocker punkRocker = await this.DocumentClient.ExecuteStoredProcedureAsync<PunkRocker>(new Uri(storedProcedure.SelfLink), partitionKey);

            if (punkRocker != null)
            {
                return punkRocker;
            }
        }

        return null;
    }

答案 2 :(得分:0)

刚试过这种方法,它不起作用。

client.CreateStoredProcedureQuery( link, String.Format( "select * from root r where r.id = '{0}'", "spname1" ) ).ToList(  ).FirstOrDefault( );

返回null

client.CreateStoredProcedureQuery( link, String.Format( "select * from root r" ) ).ToList( ).FirstOrDefault( );

返回正确的存储过程

{
    "id": "spname1",
    "body": "function() {  
        var context = getContext();
        var collection = context.getCollection();       
    }",
    "_rid": "XXX",
    "_ts": 1410449011.0,
    "_self": "XXX",
    "_etag": "XXX"
}

答案 3 :(得分:0)

您可以先在.NET SDK中查找数据库中的SP

StoredProcedure storedProcedure = Client.CreateStoredProcedureQuery(GetCollection(eColl).SelfLink).Where(c => c.Id == "SP name").AsEnumerable().FirstOrDefault();

答案 4 :(得分:0)