使用 Azure 门户创建存储过程

存储过程是你可以在 Azure Cosmos DB 中执行业务逻辑服务器端的方法之一。 使用存储过程,可以在单个事务范围内使用容器对多个文档执行基本的 CRUD(创建、读取、更新、删除)操作。

在本实验室中,你将创作一个在容器内创建文档的存储过程。 然后,使用 SQL 查询来验证存储过程的结果。

创作存储过程

存储过程是用语言集成的 JavaScript 编写的,支持在数据库引擎内执行基本 CRUD 操作。 在数据库引擎内运行的 JavaScript 是通过 Azure Cosmos DB 的服务器端 JavaScript SDK 和一系列辅助方法实现的。

  1. 在新的 Web 浏览器窗口或选项卡中,导航到 Azure 门户 (portal.azure.com)。

  2. 使用与你的订阅关联的 Microsoft 凭证登录到门户。

  3. 选择“+ 创建资源”,搜索“Cosmos DB”,然后使用以下设置创建新的“Azure Cosmos DB for NoSQL”帐户资源,并将所有其余设置保留为默认值:

    设置
    订阅 你的现有 Azure 订阅
    资源组 选择现有资源组,或创建新资源组
    帐户名 输入全局唯一名称
    位置 选择任何可用区域
    容量模式 预配的吞吐量
    应用免费分级折扣 不应用

    📝 你的实验室环境可能存在阻止你创建新资源组的限制。 如果是这种情况,请使用现有的预先创建的资源组。

  4. 等待部署任务完成,然后继续执行此任务。

  5. 转到新创建的 Azure Cosmos DB 帐户资源,并导航到“数据资源管理器”窗格。

  6. 在“数据资源管理器”** 中,选择**“新建容器”,然后创建一个具有以下设置的新容器,并将所有其余设置保留为其默认值:

    设置
    数据库 ID 新建 | cosmicworks**
    在容器之间共享吞吐量 选择此选项
    数据库吞吐量 手动 | 400
    容器 ID products
    索引 自动
    分区键 /categoryId
  7. 在“数据资源管理器”** 中,展开“cosmicworks”** 数据库节点,然后在“NoSQL API”** 导航树中选择新“products”** 容器节点。

  8. 选择“新建存储过程”。**

  9. 在“存储过程 ID”字段中,输入值“createDoc”。****

  10. 删除编辑器区域的内容。

  11. 创建一个名为 createDoc 的新 JavaScript 函数,该函数没有输入参数:**

     function createDoc() {
            
     }
    
  12. 在 createDoc 函数中,调用内置的 **getContext 方法,将结果存储在名为 context 的变量中:**

     var context = getContext();
    
  13. 调用上下文对象的 getCollection 方法,并将结果存储在名为 container 的变量中:**

     var container = context.getCollection();
    
  14. 创建一个名为 doc 的新对象,包含以下两个属性**

    属性
    Name first document**
    类别 ID demo**
     var doc = {
         name: 'first document',
         categoryId: 'demo'
     };
    
  15. 调用容器对象的 createDocument** 方法,将调用容器对象的 getSelfLink** 方法的结果和新文档作为参数传入:

     container.createDocument(
       container.getSelfLink(),
       doc
     );
    
  16. 完成后,存储过程代码现在应包括:

     function createDoc() {
       var context = getContext();
       var container = context.getCollection();
       var doc = {
         name: 'first document',
         categoryId: 'demo'
       };
       container.createDocument(
         container.getSelfLink(),
         doc
       );
     }
    
  17. 选择**“保存”以保留对存储过程所做的更改。

  18. 选择**“执行”,然后使用以下输入参数执行存储过程:

    设置 Key
    分区键值 字符串** demo**
  19. 看到空的结果。 虽然存储过程已成功执行,但 JavaScript 代码从未返回人类可读的响应。

实现存储过程的最佳做法

虽然之前在本实验室中创作的存储过程具有基本的功能,但它也缺少一些应在所有存储过程中实现的常见错误处理技巧。 首先,存储过程假定它将始终有时间完成操作,并且不会检查 ** createDocument 方法的返回值以确保它有足够的时间。 其次,存储过程假定已成功插入所有文档,而不会检查或抛出任何潜在的错误消息。 最后,存储过程不会将新创建的文档作为最初调用存储过程的请求的 HTTP 响应返回。 你将对存储过程进行这三项更改,以实现常见的最佳做法。

  1. 返回到 createDoc 存储过程的** 编辑器。

  2. 在定义 createDoc** 函数的代码中找到第 1 行:

     function createDoc() {
    

    更新代码行以包含名为 title 的参数**

     function createDoc(title) {
    
  3. 在设置 doc 对象的 name** 属性的代码中找到第 5 行:**

     name: 'first document',
    

    更新代码行以使用 title 参数** 的值:

     name: title,
    
  4. 在调用 createDocument** 方法的代码中找到第 8 行:

     container.createDocument(
    

    更新代码行,将方法调用的结果存储在名为 accepted 的变量中**

     var accepted = container.createDocument(
    
  5. 在 createDocument** 方法调用后添加一个新的代码行,以检查 accepted 变量的值,如果不为 true,则返回该方法:**

     if (!accepted) return;
    
  6. 最后,向 createDocument** 方法调用添加第三个参数,该参数是一个函数,它采用 error** 和 newDoc** 这两个参数,检查错误是否为 null,然后将 newDoc 设置为存储过程的响应正文:

     ,
     (error, newDoc) => {
       if (error) throw new Error(error.message);
       context.getResponse().setBody(newDoc);
     }
    
  7. 完成后,存储过程代码现在应包括:

     function createDoc(title) {
       var context = getContext();
       var container = context.getCollection();
       var doc = {
         name: title,
         categoryId: 'demo'
       }
       var accepted = container.createDocument(
         container.getSelfLink(),
         doc,
         (error, newDoc) => {
           if (error) throw new Error(error.message);
           context.getResponse().setBody(newDoc);
         }
       );
       if (!accepted) return;
     }
    
  8. 选择“更新”以保留对存储过程所做的更改**

  9. 选择**“执行”,然后使用以下输入参数执行存储过程:

    设置 Key
    分区键值 字符串** demo**
    输入参数 字符串** second document**
  10. 看到 JSON 结果。 成功执行存储过程后,新创建的文档已作为原始 HTTP 请求的响应返回。

查询文档

最后,你将使用数据资源管理器发出 SQL 查询,该查询将返回在本实验室中创建的两个文档。

  1. 在“数据资源管理器”** 中,展开“cosmicworks”** 数据库节点,然后在“NoSQL API”** 导航树中选择“products”** 容器节点。

  2. 选择“新建 SQL 查询”。

  3. 删除编辑器区域的内容。

  4. 创建一个新的 SQL 查询,该查询将返回 categoryId** 为 ** demo 的所有文档:

     SELECT * FROM docs WHERE docs.categoryId = 'demo'
    
  5. 选择“执行查询”。

  6. 看到在本实验室中创建的两个文档作为执行此查询的结果。

  7. 关闭 Web 浏览器窗口或选项卡。