Как выполнить существующую хранимую процедуру в DocumentDB?

Я хочу создать хранимую процедуру в DocumentDB и использовать ее, когда мне понадобится позже. Чтобы выполнить хранимую процедуру, мне нужно знать storeProcedureLink. Когда я регистрирую хранимую процедуру с помощью метода CreateStoredProcedureAsync, я получаю ссылку, должен ли я хранить эту ссылку где-то сам, если я хочу выполнить эту хранимую процедуру позже? Могу ли я выполнить хранимую процедуру, если все, что я знаю, это имя процедуры? Из всех примеров, которые я нашел, кажется, что мне нужно создать и зарегистрировать хранимую процедуру прямо перед тем, как мне нужно ее выполнить, так ли это?


person Ivan P.    schedule 11.09.2014    source источник


Ответы (5)


Только что попробовал этот подход, и он не работает.

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

возвращает ноль

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"
}
person Maxim    schedule 11.09.2014
comment
Я считаю, что client.CreateStoredProcedureQuery( link, String.Format( "select * from root r where r.id = '{0}'", "spname1" ) ).ToList( ).FirstOrDefault( ); запрашивает хранимую процедуру с id='{0}', а не с id='spname1'; вместо этого вы должны запросить r.id = 'spname'. - person Andrew Liu; 12.09.2014
comment
Это не имеет никакого смысла, так как string.format создаст соответствующую строку, прежде чем отправить ее в DocumentDB. - person Maxim; 12.09.2014
comment
Ах да, ты прав! Интересно, что я просто скопировал и запустил client.CreateStoredProcedureQuery( link, String.Format( "select * from root r where r.id = '{0}'", "spname1" ) ).ToList( ).FirstOrDefault( );, и он вернул мою процедуру сохранения. Можете ли вы опубликовать более крупный фрагмент кода, чтобы предоставить больше контекста? - person Andrew Liu; 13.09.2014

Вы можете создать хранимую процедуру заранее и сохранить ее на сервере для использования в будущем. Вам не нужно создавать его непосредственно перед использованием. Это было только для примера. Мы ожидаем, что в большинстве случаев хранимые процедуры уже существуют, и вы просто используете их в своем приложении.

Вам нужен 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< /а>

person Ryan CrawCour    schedule 11.09.2014
comment
Почему это так сложно найти... Каждый пример, который я нашел, был о создании sprocs, и это первый, описывающий наиболее распространенный сценарий == выполнение sproc и получение данных... - person Chris Hermut; 30.05.2015
comment
Если я попробую StoredProcedure sproc = client.CreateStoredProcedureQuery(collection.StoredProceduresLink, "select * from root r where r.id = \"sproc name\""); в Visual Studio 2015, компилятор жалуется Не удается неявно преобразовать тип «System.Linq.IQueryable‹dynamic›» в «Microsoft.Azure.Documents.StoredProcedure» - person sh1rts; 25.09.2015
comment
Райан КроуКур, Спасибо за ответ. Образцы ссылаются теперь на 404-е. - person t.888; 03.02.2017

Из всех примеров, которые я нашел, кажется, что мне нужно создать и зарегистрировать хранимую процедуру прямо перед тем, как мне нужно ее выполнить, так ли это?

Нет. Создание и регистрация хранимой процедуры не обязательно должны происходить во время выполнения.

Образцы носят образовательный характер, но не предлагают реальных моделей. См. основные операции CRUD DocumentManagement< /а>. Образцы также предполагают единую коллекцию. См. раздел Разделение основных операций CRUD< /а>.

Хотя я приветствую адаптацию DocumentDB соглашений о кодировании SQL, шаблон использования в настоящее время не подходит для разработчиков .NET. Десятилетний шаблон создания хранимых процедур CRUD в SQL Server и последующего вызова их по имени через ADO.NET или 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;
    }
person SawtoothPunk    schedule 30.09.2015
comment
Итак, хранимая процедура выполняется один раз для каждого раздела? Что, если запрос внутри хранимой процедуры делает что-то вроде select * from root и возвращает первые три? - person pfunk; 03.11.2015
comment
Re: найти sproc по имени: разве это не чище? Есть ли недостатки? _client.ReadStoredProcedureAsync( UriFactory.CreateStoredProcedureUri(databaseId, collectionId, sprocId) - person Cristian Diaconescu; 19.06.2017

Вы можете сначала найти SP в БД в .NET SDK.

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

Похоже, Microsoft сейчас предоставляет несколько примеров выполнения хранимых процедур: https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.documents.client.documentclient.executestoredprocedureasync?view=azure-dotnet

person Papa Stahl    schedule 27.07.2018