• Azure Cosmos DB 中 Document API 存储过程、触发器、自定义函数的实现


    阅读 大约需要 4 分钟

      在上一篇随笔中记录的是关于Azure Cosmos DB 中SQL API (DocumentDB) 的简介和Repository 的实现。本随笔是Document DB 中存储过程(Stored Procedure)、触发器(Triggers)、用户自定义函数(User Defined Functions)的实现方式。

    存储过程(Stored Procedure)

    1. 创建存储过程,需要四个参数,以此分别为数据库名,collection名,需要创建的存储过程名,存储过程的内容(内容使用的语言请参照官网:https://docs.microsoft.com/zh-cn/azure/cosmos-db/how-to-write-stored-procedures-triggers-udfs)

    注: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)为存储过程可能需要的参数.

    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 和 TriggerType

      TriggerOperation 参数有五种类型,分别为:

        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 

  • 相关阅读:
    DataGridView 设置行不可见时,与货币管理器的位置关联的行不能设置为不可见
    DataGridView 冻结列后出现 无法添加该列,原因是它被冻结并被置于未冻结的列之后
    sql 2000 查询中增加序号列,自动增加列
    SQL 语法大全
    清除vs2003vs2008起始页最近打开项目
    ALTER TABLE 修改表时 因为有一个或多个对象访问此列
    UNIX上C++程序设计守则(信号和线程)(上)
    Thread Cancel 指南
    [C++再学习系列] 深入new/delete:New的3种形态
    设计模式学习(六):重构与模式,推荐书籍(完)
  • 原文地址:https://www.cnblogs.com/OneManStep/p/10266217.html
Copyright © 2020-2023  润新知