欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-25 13:00:43
阅读 大约需要 4 分钟 在上一篇随笔中记录的是关于Azure Cosmos DB 中SQL API (DocumentDB) 的简介和Repository 的实现。本随笔是Document DB 中存储过程(Stored Procedure)、触发器(Triggers)、用户自定义函数(User ......

阅读 大约需要 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传入,其中传入的方式需要注意下,传入的类型按照前触发器和后触发器两种参入,如图:

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

怎么传,举个例子: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