Azure Cosmos DB 中 Document API 存儲過程、觸發器、自定義函數的實現

閱讀 大約須要 4 分鐘javascript

  在上一篇隨筆中記錄的是關於Azure Cosmos DB 中SQL API (DocumentDB) 的簡介和Repository 的實現。本隨筆是Document DB 中存儲過程(Stored Procedure)、觸發器(Triggers)、用戶自定義函數(User Defined Functions)的實現方式。html

 

存儲過程(Stored Procedure)java

1. 建立存儲過程,須要四個參數,以此分別爲數據庫名,collection名,須要建立的存儲過程名,存儲過程的內容(內容使用的語言請參照官網:https://docs.microsoft.com/zh-cn/azure/cosmos-db/how-to-write-stored-procedures-triggers-udfs)sql

注:catch execption只是簡寫,拋出異常。 數據庫

public async Task<bool> CreateStoredProcedureAsync(string databaseName, string collectionName, string storedProId, string body)
        {
            try
            {
                var sproc = new StoredProcedure()
                {
                    Id = storedProId,
                    Body = body
                };
                var uri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);
                await TryDeleteStoredProcedure(uri, storedProId);
                var result = await _client.Value.CreateStoredProcedureAsync(uri, sproc);

                return result.StatusCode == HttpStatusCode.OK || result.StatusCode == HttpStatusCode.Created;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

// 爲避免重複的存儲過程名 而引起的的異常(如下觸發器,自定義函數類同)。
private async Task TryDeleteStoredProcedure(Uri uri, string storedProId)
        {
            var sproc = _client.Value.CreateStoredProcedureQuery(uri).Where(x => x.Id == storedProId).AsEnumerable().FirstOrDefault();

            if (sproc != null)
            {
                await _client.Value.DeleteStoredProcedureAsync(sproc.SelfLink);
            }
        }

  

2. 讀取存儲過程,第四個參數(procedureParams)爲存儲過程可能須要的參數.async

public async Task<T> ExecuteStoredProcedureAsync<T>(string databaseName, string collectionName, string storedProId, params object[] procedureParams) where T : new()
        {
            StoredProcedureResponse<dynamic> result = await _client.Value.ExecuteStoredProcedureAsync<dynamic>(UriFactory.CreateStoredProcedureUri(databaseName, collectionName, storedProId), procedureParams);

            if (result.StatusCode == HttpStatusCode.OK)
            {
                return JsonConvert.DeserializeObject<T>(result.Response?.ToString());
            }

            throw new ArgumentException("Execute stored ptocedure failed");
        }

  

觸發器(Triggers)函數

1. 建立觸發器學習

public async Task<bool> CreateTriggerAsync(string databaseName, string collectionName, string triggerId, string triggerBody, TriggerOperation triggerOperation, TriggerType triggerType)
        {
            try
            {
                var trigger = new Trigger()
                {
                    Id = triggerId,
                    Body = triggerBody,
                    TriggerOperation = triggerOperation,
                    TriggerType = triggerType
                };
                var uri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);
                await TryDeleteTrigger(uri, triggerId);
                var result = await _client.Value.CreateTriggerAsync(uri, trigger);

                return result.StatusCode == HttpStatusCode.OK || result.StatusCode == HttpStatusCode.Created;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

private async Task TryDeleteTrigger(Uri uri, string triggerId)
        {
            var trigger = _client.Value.CreateTriggerQuery(uri).Where(x => x.Id == triggerId).AsEnumerable().FirstOrDefault();

            if (trigger != null)
            {
                await _client.Value.DeleteTriggerAsync(trigger.SelfLink);
            }
        }

 以上代碼中有兩個傳入參數TriggerOperation 和 TriggerTypespa

  TriggerOperation 參數有五種類型,分別爲:3d

    All = 0,
    Create = 1,
    Update = 2,
    Delete = 3,
    Replace = 4

  TriggerType 參數有兩種類型,分別爲前觸發器 TriggerType(Pre = 0)和 後觸發器(Post = 1)。

 

2. 使用觸發器

public async Task<bool> CreateDocumentAsync<T>(string databaseName, string collectionName, T document, RequestOptions requestOptions) where T : class
        {
            try
            {
                await CreateDocumentCollectionAsync(collectionName, databaseName);
                var uri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);

                var response = await _client.Value.CreateDocumentAsync(uri, document, requestOptions);

                bool result = (response != null && (response.StatusCode == HttpStatusCode.Created || response.StatusCode == HttpStatusCode.OK));

                return result;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

其中RequestOptions 參數能夠做爲觸發器Id/name傳入,其中傳入的方式須要注意下,傳入的類型按照前觸發器和後觸發器兩種參入,如圖:

怎麼傳,舉個例子:var option = new RequestOptions() { PreTriggerInclude = new List<string>() { "GetBrithDate" } };

 

用戶自定義函數(User Defined Functions)

1. 建立用戶自定義函數

public async Task<bool> CreateUserDefinedFunctionAsync(string databaseName, string collectionName, string udfId, string body)
        {
            try
            {
                var udf = new UserDefinedFunction()
                {
                    Id = udfId,
                    Body = body
                };
                var uri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);
                await TryDeleteUserDefinedFunction(uri, udfId);
                var result = await _client.Value.CreateUserDefinedFunctionAsync(uri, udf);

                return result.StatusCode == HttpStatusCode.OK || result.StatusCode == HttpStatusCode.Created;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

private async Task TryDeleteUserDefinedFunction(Uri uri, string udfId)
        {
            var udf = _client.Value.CreateUserDefinedFunctionQuery(uri).Where(x => x.Id == udfId).AsEnumerable().FirstOrDefault();

            if (udf != null)
            {
                await _client.Value.DeleteUserDefinedFunctionAsync(udf.SelfLink);
            }
        }

 

2. 運用自定義函數

public async Task<IEnumerable<T>> GetDocumentByUDF<T>(string databaseName, string collectionName, string sqlExpression, FeedOptions feedOptions = null) where T : new()
        {
            try
            {
                var uri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);
                var query = _client.Value.CreateDocumentQuery<T>(uri, sqlExpression, feedOptions).AsDocumentQuery();

                var results = new List<T>();
                while (query.HasMoreResults)
                {
                    results.AddRange(await query.ExecuteNextAsync<T>());
                }

                return results;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

        }

sqlExpression 爲傳入的sql 語句,具體 這個sql 語句怎麼寫,例如:

其中 數據庫中用戶自定義函數是這樣定義的:

function getTitle(profession) {

    if (profession === undefined)
        throw 'no input';

    if (profession === "Angular" || profession === "Vue" || profession  === "React")
        return "FrontEnd";
    else if (profession === "Net" || profession === "Java")
        return "BackEnd";
    else
        return "FullStack";
}

那麼 sqlExpression = $"SELECT * FROM c where udf.getTitle(c.Profession) = '{換成插入值}'";

 

簡單筆記,還有待繼續挖掘,正在繼續努力,想要了解和學習的 還請 切到Cosmos DB官網:https://docs.microsoft.com/zh-cn/azure/cosmos-db/how-to-write-stored-procedures-triggers-udfs

本隨筆連接:https://www.cnblogs.com/OneManStep/p/10266217.html 

相關文章
相關標籤/搜索