【问题标题】:Stored Procedure in .NET Core with CosmosDB gives error 500带有 CosmosDB 的 .NET Core 中的存储过程给出错误 500
【发布时间】:2017-09-27 09:01:45
【问题描述】:

所以我正在尝试为原型 Web 应用程序创建一个存储过程。 我的类/文档名称是“Plan”,它有一个 Description 属性和一个 OrderingNumber 属性作为 int - 这些的实际功能是对这个问题并不完全重要,所以让我们把它排除在外。

数据库称为“PlanDB”,我希望在其上执行存储过程的集合称为“Plans”,当然,我也保存了存储过程。

这是我的 C# 应用程序中的函数:

PlanService.cs

    public async Task SwapOrderingNumbers(string id1, string id2)
    {
        try
        {
            await client.ExecuteStoredProcedureAsync<bool>(UriFactory.CreateStoredProcedureUri("PlanDB", "Plans", "swapOrderNumberSproc"), id1, id2);
        }
        catch (DocumentClientException de)
        {
            throw;
        }
    }

如您所见,我有参数 id1 和 id2,我希望在执行所述存储过程时使用它们——理想情况下,它应该交换 2 个 OrderingNumber计划

swapOrderNumberSproc

    // Stored procedure for swapping ordering numbers
    //  @param planId1 - Plan 1's ID 
    //  @param planId2 - Plan 2's ID 

var swapOrderNumberSproc = {
id: "swapOrderNumberSproc",
serverScript: function (planId1, planId2) {
    var context = getContext();
    var collection = context.getCollection();
    var response = context.getResponse();

    var plan1Document, plan2Document;

    // query for Plans
    var filterQuery = 'SELECT * FROM Plans a where a.id  = "' + planId1 + '"';
    var accept = collection.queryDocuments(collection.getSelfLink(), filterQuery, {},
        function (err, documents, responseOptions) {
            if (err) throw new Error("Error" + err.message);

            if (documents.length != 1) throw "Unable to find both names";
            plan1Document = documents[0];

            var filterQuery2 = 'SELECT * FROM Plans a where a.id = "' + planId2 + '"';
            var accept2 = collection.queryDocuments(collection.getSelfLink(), filterQuery2, {},
                function (err2, documents2, responseOptions2) {
                    if (err2) throw new Error("Error" + err2.message);
                    if (documents2.length != 1) throw "Unable to find both names";
                    plan2Document = documents2[0];
                    swapOrder(plan1Document, plan2Document);
                    return;
                });
            if (!accept2) throw "Unable to read Plan details, abort ";
        });

    if (!accept) throw "Unable to read Plan details, abort ";

    // swap the two Plans’ OrderingNumbers
    function swapOrder(plan1, plan2) {
        var plan1NumberSave = plan1.OrderingNumber;
        plan1.OrderingNumber = plan2.OrderingNumber;
        plan2.OrderingNumber = plan1NumberSave;

        var accept = collection.replaceDocument(plan1._self, plan1,
            function (err, docReplaced) {
                if (err) throw "Unable to update Plan 1, abort ";

                var accept2 = collection.replaceDocument(plan2._self, plan2,
                    function (err2, docReplaced2) {
                        if (err) throw "Unable to update Plan 2, abort"
                    });

                if (!accept2) throw "Unable to update Plan 2, abort";
            });

        if (!accept) throw "Unable to update Plan 1, abort";
    }
}

来自 C# 的 SwapOrderingNumbers() 在我的控制器中的端点“/swapnumbers”通过 POST 调用:

PlansController

    [Route("swapnumbers")]
    [HttpPost]
    public async Task SwapOrderingNumbers()
    {
        await activityService.SwapOrderingNumbers("ca35e414-f1b8-49dc-89e7-61e2e100d14a", "dd4a8298-55b8-425b-b16b-f73229399107");

    }

目前,作为参数给出的 ID 被硬编码以简化。

每当我尝试通过 POST 执行存储过程时,它都会返回错误 500。我做错了什么?

编辑

追踪

    Microsoft.Azure.Documents.BadRequestException: Message: {"Errors":
    ["Encountered exception while compiling Javascript. Exception = 
    SyntaxError: Syntax error\r\nSource information: line: 5, column: 1, 
    source line:\r\nvar swapOrderNumberSproc = {"]}
    ActivityId: bf1bacba-0375-4a51-9c94-07c89dfb4868, Request URI: 
    /apps/DocDbApp/services/DocDbServer19/partitions/a4cb495f-38c8-11e6-
    8106-8cdcd42c33be/replicas/1p/
    at Microsoft.Azure.Documents.TransportClient.ThrowIfFailed(String 
    resourceAddress, StoreResponse storeResponse, Uri physicalAddress, Guid 
    activityId)
    at Microsoft.Azure.Documents.RntbdTransportClient.
    <InvokeStoreAsync>d__3.MoveNext()

我从存储过程中删除的部分

    var swapOrderNumberSproc = {
    id: "swapOrderNumberSproc",
    serverScript: 

替换为

    function swapOrderNumberSproc(activityId1, activityId2) {

【问题讨论】:

  • 您是否尝试查看 SPROC 调用的响应或实际检查异常是什么?
  • 你能分享堆栈跟踪吗?您的收藏是否已分区?
  • 我已在原帖底部添加了跟踪。集合未分区。
  • 我删除了第 5 行异常中指出的问题——将准确地发布原始帖子中的哪一部分——并且现在可以根据需要交换值。但是,它在发布时仍然返回错误 500。
  • 很抱歉向 cmets 发送垃圾邮件——这方面很新,忘记标记了。 @MatiasQuaranta

标签: c# .net stored-procedures azure-cosmosdb


【解决方案1】:

看来您的 SP 脚本应该以 function swapOrderNumberSproc (planId1, planId2){ 开头。

function swapOrderNumberSproc(planId1, planId2) {
var context = getContext();
var collection = context.getCollection();
var response = context.getResponse();

var plan1Document, plan2Document;

// query for Plans
var filterQuery = 'SELECT * FROM Plans a where a.id  = "' + planId1 + '"';
var accept = collection.queryDocuments(collection.getSelfLink(), filterQuery, {},
    function (err, documents, responseOptions) {
        if (err) throw new Error("Error" + err.message);

        if (documents.length != 1) throw "Unable to find both names";
        plan1Document = documents[0];

        var filterQuery2 = 'SELECT * FROM Plans a where a.id = "' + planId2 + '"';
        var accept2 = collection.queryDocuments(collection.getSelfLink(), filterQuery2, {},
            function (err2, documents2, responseOptions2) {
                if (err2) throw new Error("Error" + err2.message);
                if (documents2.length != 1) throw "Unable to find both names";
                plan2Document = documents2[0];
                swapOrder(plan1Document, plan2Document);
                response.setBody(true);
            });
        if (!accept2) throw "Unable to read Plan details, abort ";
    });

if (!accept) throw "Unable to read Plan details, abort ";

// swap the two Plans’ OrderingNumbers
function swapOrder(plan1, plan2) {
    var plan1NumberSave = plan1.OrderingNumber;
    plan1.OrderingNumber = plan2.OrderingNumber;
    plan2.OrderingNumber = plan1NumberSave;

    var accept = collection.replaceDocument(plan1._self, plan1,
        function (err, docReplaced) {
            if (err) throw "Unable to update Plan 1, abort ";

            var accept2 = collection.replaceDocument(plan2._self, plan2,
                function (err2, docReplaced2) {
                    if (err) throw "Unable to update Plan 2, abort"
                });

            if (!accept2) throw "Unable to update Plan 2, abort";
        });

    if (!accept) throw "Unable to update Plan 1, abort";
}
}

此外,您在任何时候都不会返回bool,您必须发送response 中的值。我将您的return; 更改为response.setBody(true);

在那次重构之后,我能够从 C# 运行它而不会出现编译错误并返回 bool

【讨论】:

  • 谢谢你!实施您的更改后,我现在在调用存储过程时得到 200 OK。
猜你喜欢
  • 2020-02-29
  • 2017-03-04
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 2012-11-06
  • 1970-01-01
  • 2020-11-23
相关资源
最近更新 更多