Connect Azure Functions to Azure SQL Database using Visual Studio Code

Azure Functions 讓你能將 Azure 服務和其他資源連接到函數,而不必自己寫整合程式碼。 這些繫結同時代表輸入和輸出,會宣告於函式定義內。 繫結中的資料會提供給函式作為參數。 「觸發程序」是一種特殊的輸入繫結。 雖然函式只有一個觸發器,但可以有多個輸入和輸出綁定。 想了解更多,請參考Azure Functions觸發與綁定概念

這篇文章會教你如何用 Visual Studio Code 將 Azure SQL Database 連接到你在上一篇快速入門文章中建立的函式。 你加到這個函式上的輸出綁定會把 HTTP 請求的資料寫到 Azure SQL Database 中的一個資料表。

在開始之前,你必須完成 quickstart:使用 Visual Studio Code 在 Azure 建立 C# 函式。 如果你已經在那篇文章結尾整理過資源,請再做一次步驟,在 Azure 中重新建立功能應用程式和相關資源。

在開始之前,您必須完成快速入門:使用 Visual Studio Code 在 Azure 建立 JavaScript 函式。 如果你已經在那篇文章結尾整理過資源,請再做一次步驟,在 Azure 中重新建立功能應用程式和相關資源。

在開始之前,你必須完成 quickstart:使用 Visual Studio Code 在 Azure 建立 Python 函式。 如果你已經在那篇文章結尾整理過資源,請再做一次步驟,在 Azure 中重新建立功能應用程式和相關資源。

關於Azure SQL綁定與Azure Functions觸發設定的更多細節,請參閱Azure Functions文件。

建立你的 Azure SQL Database

  1. 請依照 Azure SQL Database 快速入門指南 建立無伺服器的 Azure SQL Database。 資料庫可以是空的,也可以從範例資料集 AdventureWorksLT 建立。

  2. 請在提示中提供下列資訊:

    提示 選擇
    資源群組 選擇您在先前的文章中建立函式應用程式所在的資源群組。
    資料庫名稱 輸入 mySampleDatabase
    伺服器名稱 輸入伺服器的唯一名稱。 我們無法提供精確的伺服器名稱,因為伺服器名稱必須對 Azure 中所有伺服器全域唯一,而非訂閱內唯一。
    驗證方法 選擇 SQL Server authentication
    伺服器管理員登入 輸入 azureuser
    密碼 輸入符合複雜性需求的密碼。
    允許Azure服務與資源access此伺服器 選取 [是]

    重要

    本文目前展示如何透過 SQL Server 認證連接 Azure SQL Database。 為了達到最佳安全性,你應該改用管理身份來連接 Azure SQL Database。 如需詳細資訊,請參閱建立具有使用者指派受控識別的 Azure SQL Database 伺服器

  3. 建立完成後,前往 Azure portal 中的資料庫面板,在 Settings 中選擇 Connection strings。 複製 ADO.NET 連接字串 用於 SQL 認證。 將 connection string 貼到暫存文件中以備後用。

    在 Azure 入口網站中複製 Azure SQL Database 連接字串的截圖。

  4. 建立資料表,儲存來自 HTTP 要求的資料。 在 Azure portal 中,導向資料庫面板,選擇Query editor。 輸入下列查詢,建立名為 dbo.ToDo 的資料表:

    CREATE TABLE dbo.ToDo (
        [Id] UNIQUEIDENTIFIER PRIMARY KEY,
        [order] INT NULL,
        [title] NVARCHAR(200) NOT NULL,
        [url] NVARCHAR(200) NOT NULL,
        [completed] BIT NOT NULL
    );
    
  5. 請檢查 server 的防火牆設定,確認你的 Azure 功能能access Azure SQL Database。 請前往 Azure 入口網站上的 server blade,在 Security 中選擇 Networking允許Azure服務與資源access此伺服器的例外應被勾選。

    在 Azure 入口網站中檢查 Azure SQL 資料庫防火牆設定的截圖。

更新函式應用程式的設定

先前的快速入門文章中,你在 Azure 上創建了一個函式應用。 在本文中,你將更新應用程式,將資料寫入你剛建立的 Azure SQL Database。 要連接你的 Azure SQL Database,必須將它的 connection string 加入應用程式設定。 接著你下載新的設定到 local.settings.json 檔案,這樣本地運行時就能連接到Azure SQL Database。

  1. 編輯你之前創建的暫存文件中的連接字串(connection string)。 把 Password 的值替換成你建立Azure SQL Database時使用的密碼。 複製更新後的連接字串。

  2. Ctrl/Cmd+shift+P 開啟指令面板,然後搜尋並執行指令 Azure Functions: Add New Setting...

  3. 選擇您在上一篇文章中建立的函式應用程式。 請在提示中提供下列資訊:

    提示 選擇
    輸入新的應用程式設定名稱 輸入 SqlConnectionString
    輸入 "SqlConnectionString" 的值 貼上你剛複製的 Azure SQL Database 的 connection string。

    這會在 Azure 的您的函式應用程式中建立一個名為 connection SqlConnectionString 的應用程式設定。 現在,您可以將此設定下載到您的 local.settings.json 檔案。

  4. 再次按 Ctrl/Cmd+shift+P 開啟指令面板,然後搜尋並執行指令 Azure Functions: Download Remote Settings...

  5. 選擇您在上一篇文章中建立的函式應用程式。 選取全部皆是,以覆寫現有的本機設定。

這將把 Azure 的所有設定下載到你的本地專案,包括新的連接字串設定。 下載的設定大部分在本機執行時不會使用。

註冊繫結延伸模組

因為你使用的是 Azure SQL 輸出綁定,執行 project 前必須先安裝對應的綁定擴充功能。

除了 HTTP 和計時器觸發程序之外,繫結皆會以擴充套件的形式實作。 在終端機視窗執行以下 dotnet add package 指令,將 Azure SQL 擴充套件加入你的project。

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Sql

您的project已設定為使用 extension bundles,會自動安裝一組預設的擴充套件。

擴充包的使用在project根的 host.json 檔案中被啟用,顯示如下:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  },
  "concurrency": {
    "dynamicConcurrencyEnabled": true,
    "snapshotPersistenceEnabled": true
  }
}

:::

現在,你可以把 Azure SQL 的輸出綁定加到你的 project 裡。

新增輸出繫結

在函式中,每一種繫結都需要在 function.json 檔案中定義 directiontype 和唯一的 name。 定義這些屬性的方式會取決於您函式應用程式的語言。

打開 HttpExample.cs project 檔案,並新增以下 ToDoItem 類別,定義寫入資料庫的物件:

namespace AzureSQL.ToDo
{
    public class ToDoItem
    {
        public Guid Id { get; set; }
        public int? order { get; set; }
        public string title { get; set; }
        public string url { get; set; }
        public bool? completed { get; set; }
    }
}

在 C# 類別函式庫 project 中,綁定定義為函式方法上的綁定屬性。 接著,系統會根據這些屬性自動產生函式所需的 function.json 檔案。

打開 HttpExample.cs project 檔案,新增以下輸出類型類別,定義了 HTTP 回應與 SQL 輸出中函式將產生的組合物件:

public static class OutputType
{
    [SqlOutput("dbo.ToDo", connectionStringSetting: "SqlConnectionString")]
    public ToDoItem ToDoItem { get; set; }
    public HttpResponseData HttpResponse { get; set; }
}

在檔案頂端的 Microsoft.Azure.Functions.Worker.Extensions.Sql 函式庫中新增一個 using 語句:

using Microsoft.Azure.Functions.Worker.Extensions.Sql;

系結屬性會直接在您的程式代碼中定義。 Azure SQL 輸出配置描述了Azure SQL輸出綁定所需的欄位。

在此 MultiResponse 案例中,您必須將 extraOutputs 的輸出系結新增至函式。

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToSql],
  handler: async (request, context) => {

將下列屬性新增至系結組態:

const sendToSql = output.sql({
  commandText: 'dbo.ToDo',
  connectionStringSetting: 'SqlConnectionString',
});

繫結屬性是直接定義在 function_app.py 檔案中。 你可以使用 generic_output_binding 裝飾器來新增一個 Azure SQL 輸出綁定

@app.generic_output_binding(arg_name="toDoItems", type="sql", CommandText="dbo.ToDo", ConnectionStringSetting="SqlConnectionString"
    data_type=DataType.STRING)

在這段程式碼中,arg_name 表示你程式碼中引用的綁定參數,type 表示輸出綁定是 SQL 輸出綁定,CommandText 表示綁定寫入的表格,ConnectionStringSetting 是包含該 Azure SQL connection string 的應用程式設定名稱。 connection string 位於 local.settings.json 檔案的 SqlConnectionString 設定中。

新增會使用輸出繫結的程式碼

以下列程式碼取代現有的 Run 方法:

[Function("HttpExample")]
public static OutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("HttpExample");
    logger.LogInformation("C# HTTP trigger function processed a request.");

    var message = "Welcome to Azure Functions!";

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString(message);

    // Return a response to both HTTP trigger and Azure SQL output binding.
    return new OutputType()
    {
         ToDoItem = new ToDoItem
        {
            id = System.Guid.NewGuid().ToString(),
            title = message,
            completed = false,
            url = ""
        },
        HttpResponse = response
    };
}

新增程式碼,使用 extraInputs 上的 context 輸出繫結物件,將 JSON 文件傳送至具名的輸出繫結函式 sendToSql。 在 return 陳述式前面新增此程式碼。

const data = JSON.stringify([
  {
    // create a random ID
    Id: crypto.randomUUID(),
    title: name,
    completed: false,
    url: '',
  },
]);

// Output to Database
context.extraOutputs.set(sendToSql, data);

若要利用 crypto 模組,請將下列這行新增至檔案頂端:

const crypto = require("crypto");

此時,您的函式看起來應如下所示:

const { app, output } = require('@azure/functions');
const crypto = require('crypto');

const sendToSql = output.sql({
  commandText: 'dbo.ToDo',
  connectionStringSetting: 'SqlConnectionString',
});

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToSql],
  handler: async (request, context) => {
    try {
      context.log(`Http function processed request for url "${request.url}"`);

      const name = request.query.get('name') || (await request.text());

      if (!name) {
        return { status: 404, body: 'Missing required data' };
      }

      // Stringified array of objects to be inserted into the database
      const data = JSON.stringify([
        {
          // create a random ID
          Id: crypto.randomUUID(),
          title: name,
          completed: false,
          url: '',
        },
      ]);

      // Output to Database
      context.extraOutputs.set(sendToSql, data);

      const responseMessage = name
        ? 'Hello, ' +
          name +
          '. This HTTP triggered function executed successfully.'
        : 'This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.';

      // Return to HTTP client
      return { body: responseMessage };
    } catch (error) {
      context.log(`Error: ${error}`);
      return { status: 500, body: 'Internal Server Error' };
    }
  },
});

更新 function_app.py 以符合以下程式碼。 將 toDoItems 參數新增至函式定義和 toDoItems.set() 陳述式底下的 if name:

import azure.functions as func
import logging
from azure.functions.decorators.core import DataType
import uuid

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.FUNCTION)
@app.generic_output_binding(arg_name="toDoItems", type="sql", CommandText="dbo.ToDo", ConnectionStringSetting="SqlConnectionString",data_type=DataType.STRING)
def test_function(req: func.HttpRequest, toDoItems: func.Out[func.SqlRow]) -> func.HttpResponse:
     logging.info('Python HTTP trigger function processed a request.')
     name = req.get_json().get('name')
     if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

     if name:
        toDoItems.set(func.SqlRow({"Id": str(uuid.uuid4()), "title": name, "completed": False, "url": ""}))
        return func.HttpResponse(f"Hello {name}!")
     else:
        return func.HttpResponse(
                    "Please pass a name on the query string or in the request body",
                    status_code=400
                )

在本機執行函式

Visual Studio Code 與 Azure Functions Core 工具整合,讓你能在本地開發電腦上執行此project,然後再發佈到Azure。 如果你還沒有在本地安裝 Core Tools,第一次執行 project 時會被提示安裝。

  1. 要呼叫你的函式,按 F5 啟動函式應用程式專案。 [終端] 面板會顯示核心工具的輸出。 您的應用程式會在 [終端] 面板中啟動。 您可以查看在本機所執行 HTTP 觸發函式的 URL 端點。

    Visual Studio Code 區域函式輸出截圖。

    如果您尚未安裝 Core Tools,請根據提示選擇 Install 來安裝 Core Tools。
    如果你在 Windows 上遇到困難,請確認 Visual Studio Code 的預設終端機沒有設成 WSL Bash

  2. 執行核心工具後,前往 Azure: Functions 區域。 在 Functions 下,展開 Local Project>Functions。 以滑鼠右鍵按一下 (Windows) 或 Ctrl - 點擊 (macOS) HttpExample 函式,並選擇 [立即執行函式...]

     來自 Visual Studio Code 的執行函數截圖。

  3. 輸入請求正文中,按下Enter向您的函式傳送請求訊息。

  4. 當函式在本地執行並回傳回應時,會在 Visual Studio Code 中發出通知。 終端機 面板會顯示功能執行的相關資訊。

  5. Ctrl + C 以停止 Core Tools,並中斷偵錯工具的連線。

在本機執行函式

  1. 如前文所述,按下 F5 以啟動函式應用程式專案及核心工具。

  2. 執行 Core Tools 後,請前往 Azure: Functions 區域。 在 Functions 下,展開 Local Project>Functions。 以滑鼠右鍵按一下 HttpExample 函式 (Mac 上為 Ctrl + 按一下),並選擇 [立即執行函式...]

    Visual Studio Code 執行功能現在的選單項目截圖

  3. 輸入請求主體中,你會看到請求訊息主體值為 { "name": "Azure" }。 請按 Enter 鍵,將此要求訊息傳送至您的函式。

  4. 傳回回應後,按一下 Ctrl + C 以停止 Core Tools。

確認資訊已寫入至資料庫

  1. 在 Azure 入口網站上,返回您的 Azure SQL 資料庫,然後選擇Query editor

    登入 Azure 入口網站上的查詢編輯器的截圖

  2. 連接到你的資料庫,並在左側object explorer中展開Tables節點。 以滑鼠右鍵按一下 dbo.ToDo 資料表,然後選取 [選取前 1000 列]

  3. 確認新資訊已透過輸出繫結寫入至資料庫。

重新部署並驗證更新的應用程式

  1. 在 Visual Studio Code 中,按 F1 開啟指令面板。 在指令面板中搜尋並選擇 Azure Functions: Deploy to function app...

  2. 選擇您在第一篇文章中所建立的功能應用程式。 因為你將專案重新部署到同一個應用程式,請選擇Deploy以忽略有關覆寫檔案的警告。

  3. 部署完成後,你又可以再次使用 Execute Function Now... 功能,用來觸發該功能Azure。 此指令會自動取得函式 access 金鑰,並在呼叫 HTTP 觸發端點時使用該金鑰。

  4. 檢查寫入你的 Azure SQL Database 的資料,確認輸出綁定是否會產生新的 JSON 文件。

清除資源

在 Azure 中,resources 指的是功能應用程式、函式、儲存體帳戶等等。 其會分組為「資源群組」,您可以藉由刪除群組來刪除群組中的所有項目。

您已建立資源以完成這些快速入門。 根據您的帳戶狀態服務價格,您可能會被收取這些資源的費用。 如果您不再需要資源,刪除方式如下:

  1. 在Visual Studio程式碼中,按 F1 開啟指令面板。 在指令面板中搜尋並選擇 Azure: Open in portal

  2. 選擇您的函數應用程式,並按下 Enter。 function app 頁面會在 Azure portal 開啟。

  3. 在 [概觀] 索引標籤中,選取 [資源群組] 旁的具名連結。

    函數應用程式頁面中的螢幕擷取畫面,顯示選取要刪除的資源群組。

  4. 在 [資源群組] 分頁上,檢閱所含資源的清單,並確認這些是您想要刪除的項目。

  5. 選取 [刪除資源群組],並遵循指示。

    刪除需要幾分鐘的時間。 完成時,通知會出現幾秒鐘的時間。 您也可以選取分頁頂端的鈴鐺圖示以檢視通知。

下一步

你已經更新了 HTTP 觸發函式,讓資料寫入 Azure SQL Database。 現在你可以進一步了解如何使用 Visual Studio Code 開發函式: