为分区集合保存和测试存储 Procedures/Triggers(可能是用户定义的函数)

Saving & Testing Stored Procedures/Triggers (maybe User Defined Functions) For Partitioned Collections

我在尝试将修改保存到已在分区集合中创建的存储过程时收到以下错误:

Failed to save the script

以下是 Azure 门户中的详细信息:

Operation name Failed to save the script Time stamp Fri Feb 17 2017 08:46:32 GMT-0500 (Eastern Standard Time) Event initiated by - Description Database Account: MyDocDbAccount, Script: bulkImport, Message: {"code":400,"body":"{\"code\":\"BadRequest\",\"message\":\"Replaces and upserts for scripts in collections with multiple partitions are not supported.

有问题的存储过程是可以在 here.

中找到的示例 "bulkImport" 脚本

目前 DocumentDB 中存在一个已知的缺失功能(如果您愿意,则为错误),您无法更新分区集合中的现有存储过程。解决方法是先删除它,然后在相同的 name/id.

下重新创建它

与错误消息相反,事实证明 _client.ReplaceStoredProcedureAsync(...) 在分区集合上确实有效(截至 2018 年 6 月)。所以你可以这样做:

try 
{
    await _client.CreateStoredProcedureAsync(...);
} 
catch(DocumentClientException dex) when (dex.StatusCode == HttpStatusCode.Conflict) 
{ 
    await _client.ReplaceStoredProcedureAsync(...);  
} 

一旦您的 SP 第一次创建,您将永远不会有任何时间量不可用(由于删除 + 重新创建)。

此扩展方法可以处理存储过程的添加或更新。

public static async Task AddOrUpdateProcedure(this DocumentClient client, 
    string databaseId, 
    string collectionId, 
    string storedProcedureId, 
    string storedProcedureBody)
{
    try
    {
        var documentCollectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);
        await client.CreateStoredProcedureAsync(documentCollectionUri, new StoredProcedure
        {
            Id = storedProcedureId,
            Body = storedProcedureBody
        });
    }
    catch (DocumentClientException ex) when (ex.StatusCode == HttpStatusCode.Conflict)
    {
        var storedProcedureUri = UriFactory.CreateStoredProcedureUri(databaseId, collectionId, storedProcedureId);
        var storedProcedure = await client.ReadStoredProcedureAsync(storedProcedureUri);
        storedProcedure.Resource.Body = storedProcedureBody;
        await client.ReplaceStoredProcedureAsync(storedProcedure);
    }
}

截至目前,更新存储过程在 Azure 门户/CosmosDB 数据资源管理器中仍然不起作用。有一个适用于 Visual Studio 代码的 Cosmos DB 扩展。但是,我没有看到像从 Data Explorer 中那样从扩展中执行过程的方法。

                  try
                    {
                        var spResponse = await dbClient.CreateStoredProcedureAsync($"/dbs/{dataRepoDatabaseId}/colls/{collectionName}", new StoredProcedure
                        {
                            Id = sp.Item1,
                            Body = sp.Item2
                        }, new RequestOptions { PartitionKey = new PartitionKey(partitionKey) });

                    }
                    catch (DocumentClientException dex) when (dex.StatusCode == HttpStatusCode.Conflict)
                    {
                        //Fetch the resource to be updated
                        StoredProcedure sproc = dbClient.CreateStoredProcedureQuery($"/dbs/{dataRepoDatabaseId}/colls/{collectionName}")
                                                         .Where(r => r.Id == sp.Item1)
                                                         .AsEnumerable()
                                                         .SingleOrDefault();
                        if(!sproc.Body.Equals( sp.Item2))
                        {
                            sproc.Body = sp.Item2;

                            StoredProcedure updatedSPResponse = await dbClient.ReplaceStoredProcedureAsync(sproc);

                        }
                    }