本頁說明如何使用 Data API,對 Cloud SQL 執行個體上的資料庫執行 SQL 陳述式。使用 Data API 時,您可以使用 Cloud SQL Admin API 和 gcloud CLI,在已啟用 Data API 存取的任何執行個體上執行 SQL 陳述式。
您可以在使用公開 IP 位址、私人服務存取或 Private Service Connect 的執行個體上使用 Data API。Data API 支援所有類型的 SQL 陳述式,包括資料操縱語言 (DML)、資料定義語言 (DDL) 和資料查詢語言 (DQL)。Data API 適合執行小型且快速的管理陳述式,例如建立資料庫角色或使用者,以及進行小型結構定義更新。
事前準備
您必須先完成下列步驟,才能在執行個體上執行 SQL 陳述式。
設定資料庫使用者
Data API 必須以資料庫使用者的身分通過驗證,才能執行 SQL 陳述式。
如要使用密碼以內建使用者身分進行驗證,請執行下列操作:
- 建立使用者帳戶,並設定密碼。
您也可以使用預設使用者
sqlserver。 - 授予帳戶執行 SQL 陳述式所需的角色或權限。如果使用者不是
sqlserver,請授予使用者db_owner角色。 - 使用 Secret Manager 建立區域性密鑰來儲存密碼。為確保安全,Data API 會在 API 要求中要求提供密碼的資源名稱,而不是密碼本身。區域密鑰應與 Cloud SQL 執行個體儲存在相同區域。即使是儲存在相同區域,也不支援使用 Secret Manager 的全域端點建立的密鑰。
- 最佳做法是定義 IAM 條件,允許使用者存取特定密鑰,但無法存取專案中的其他密鑰。
必要角色或權限
根據預設,具備下列任一角色的使用者或服務帳戶,有權在 Cloud SQL 執行個體上執行 SQL 陳述式 (cloudsql.instances.executesql):
Cloud SQL Admin(roles/cloudsql.admin)Cloud SQL Instance User(roles/cloudsql.instanceUser)Cloud SQL Studio User(roles/cloudsql.studioUser)
您也可以為使用者或服務帳戶定義 IAM 自訂角色,其中包含 cloudsql.instances.executesql 權限。這項權限支援身分與存取權管理 (IAM) 自訂角色。
啟用或停用 Data API
如要使用 Data API,必須為每個執行個體啟用這項功能。 您隨時可以停用 Data API。
控制台
-
前往 Google Cloud 控制台的「Cloud SQL Instances」頁面。
- 如要開啟執行個體的「總覽」頁面,請按一下執行個體名稱。
- 在 SQL 導覽選單中,選取「連線」。
- 按一下 [網路] 分頁標籤。
- 勾選「允許 Data API」核取方塊。
- 按一下 [儲存]。
gcloud
如要在執行個體上啟用 Google Data API 存取權,請使用 gcloud sql instances patch 指令並加上 --data-api-access=ALLOW_DATA_API 標記:
gcloud sql instances patch INSTANCE_NAME --data-api-access=ALLOW_DATA_API
如要停用 Google Data API 存取權,請使用 --data-api-access=DISALLOW_DATA_API 標記:
gcloud sql instances patch INSTANCE_NAME --data-api-access=DISALLOW_DATA_API
將 INSTANCE_NAME 替換為要啟用或停用 Data API 的執行個體名稱。
執行 SQL 陳述式
您可以使用 gcloud CLI 或 REST API,對 Cloud SQL 執行個體上的資料庫執行 SQL 陳述式。
使用密碼驗證
如果密碼以區域密碼的形式儲存在 Secret Manager 中,且與 Cloud SQL 執行個體位於相同區域,您可以使用內建的密碼驗證機制執行 SQL 陳述式。
gcloud
如要使用 gcloud CLI 對執行個體上的資料庫執行 SQL 陳述式,請使用 gcloud sql instances execute-sql 指令。
gcloud sql instances execute-sql INSTANCE_NAME \ --database=DATABASE_NAME \ --sql=SQL_STATEMENT \ --user=USER \ --password-secret-version=PASSWORD_SECRET_VERSION \ --partial-result-mode=PARTIAL_RESULT_MODE
請將下列項目改為對應的值:
- INSTANCE_NAME:執行個體的名稱。
- DATABASE_NAME:執行個體中的資料庫名稱。
- SQL_STATEMENT:要執行的 SQL 陳述式。如果陳述式含有空格或殼層特殊字元,就必須加上引號。
- USER:要驗證身分的資料庫使用者。
- PASSWORD_SECRET_VERSION:Secret Manager Secret 的資源名稱,其中包含資料庫使用者的密碼。密鑰應為區域密鑰,並儲存在與 Cloud SQL 執行個體相同的區域。預期的資源名稱格式為
projects/{project}/locations/{location}/secrets/{secret}/versions/{secret_version}。 - PARTIAL_RESULT_MODE:選用。控管結果不完整時的回應方式。可以是
ALLOW_PARTIAL_RESULT、FAIL_PARTIAL_RESULT或PARTIAL_RESULT_MODE_UNSPECIFIED。請參閱「修改截斷行為」。
Terraform
您可以在 Terraform 上使用 Data API,佈建資料庫內資源,例如資料庫、表格、擴充功能、使用者和權限授予,不必手動連線至執行個體。如要在 Terraform 上執行 SQL 指令碼,請使用
google_sql_provision_script Terraform 資源。
resource "google_sql_user" "built_in_user" { name = "tf-user" host = "%" # Don't set this field for PostgreSQL and SQL Server. instance = google_sql_database_instance.instance.name password = "changeme" type = "BUILT_IN" } # Create a regional secret. Global secrets are not supported even if # located in one region only. resource "google_secret_manager_regional_secret" "secret" { secret_id = "db-password" # Use the same region as the Cloud SQL instance. location = "us-central1" } resource "google_secret_manager_regional_secret_version" "secret_version" { secret = google_secret_manager_regional_secret.secret.id secret_data = "changeme" } resource "google_sql_provision_script" "script" { # You can inline the script or import from a file likescript = file("${path.module}/script.sql")# When modified, the whole script will be executed again. It's recommended to # make the script idempotent with patterns likecreate if not exists ...or #if not exists (select ...) then ... end if. script = "CREATE TABLE IF NOT EXISTS table1 ( col VARCHAR(16) NOT NULL );" instance = google_sql_database_instance.instance.name database = google_sql_database.database.name description = "sql script to create tables" user = google_sql_user.built_in_user.name # The location should be the same as the Cloud SQL instance's location. password_secret_version = "projects/my-project/locations/us-central1/secrets/db-password/versions/latest" # The built-in database user and password secret version must be created # first. Cloud SQL will retrieve password from Secret Manager # and connect to this user account to execute your script. depends_on = [ google_sql_user.built_in_user, google_secret_manager_regional_secret_version.secret_version ] }
套用變更
如要在 Google Cloud 專案中套用 Terraform 設定,請完成下列各節的步驟。
準備 Cloud Shell
- 啟動 Cloud Shell。
-
設定要套用 Terraform 設定的預設 Google Cloud 專案 。
每個專案只需要執行一次這個指令,且可以在任何目錄中執行。
export GOOGLE_CLOUD_PROJECT=PROJECT_ID
如果您在 Terraform 設定檔中設定明確值,環境變數就會遭到覆寫。
準備目錄
每個 Terraform 設定檔都必須有自己的目錄 (也稱為根模組)。
-
在 Cloud Shell 中建立目錄,並在該目錄中建立新檔案。檔案名稱的副檔名必須是
.tf,例如main.tf。在本教學課程中,這個檔案稱為main.tf。mkdir DIRECTORY && cd DIRECTORY && touch main.tf
-
如果您正在學習教學課程,可以複製每個章節或步驟中的程式碼範例。
將程式碼範例複製到新建立的
main.tf中。視需要從 GitHub 複製程式碼。如果 Terraform 程式碼片段是端對端解決方案的一部分,建議您使用這個選項。
- 查看並修改範例參數,套用至您的環境。
- 儲存變更。
-
初始化 Terraform。每個目錄只需執行一次這項操作。
terraform init
如要使用最新版 Google 供應商,請加入
-upgrade選項:terraform init -upgrade
套用變更
-
查看設定,確認 Terraform 即將建立或更新的資源符合您的預期:
terraform plan
視需要修正設定。
-
執行下列指令,並在提示中輸入
yes,套用 Terraform 設定:terraform apply
等待 Terraform 顯示「Apply complete!」訊息。
- 開啟 Google Cloud 專案即可查看結果。在 Google Cloud 控制台中,前往 UI 中的資源,確認 Terraform 已建立或更新這些資源。
刪除變更
刪除 google_sql_provision_script 資源不會刪除該資源建立的資料庫內資源。如要刪除這些變數,您可以在指令碼中明確新增 drop ... if exists 等陳述式,然後套用變更。
REST
如要使用 REST API 對執行個體上的資料庫執行 SQL 陳述式,請將 POST 要求傳送至 executeSql 端點:
POST https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_NAME/executeSql
要求主體應包含資料庫名稱和 SQL 陳述式:
{ "database": "DATABASE_NAME", "sqlStatement": "SQL_STATEMENT", "user": "USER", "passwordSecretVersion": "PASSWORD_SECRET_VERSION", "partialResultMode": "PARTIAL_RESULT_MODE" }
請將下列項目改為對應的值:
- PROJECT_ID:您的專案 ID。
- INSTANCE_NAME:執行個體的名稱。
- DATABASE_NAME:執行個體中的資料庫名稱。
- SQL_STATEMENT:要執行的 SQL 陳述式。
- USER:要驗證身分的資料庫使用者。
- PASSWORD_SECRET_VERSION:Secret Manager Secret 的資源名稱,其中包含資料庫使用者的密碼。密鑰應為區域密鑰,並儲存在與 Cloud SQL 執行個體相同的區域。預期的資源名稱格式為
projects/{project}/locations/{location}/secrets/{secret}/versions/{secret_version}。 - PARTIAL_RESULT_MODE:選用。控管結果超過 10 MB 時,API 的回應方式。可以是
FAIL_PARTIAL_RESULT、ALLOW_PARTIAL_RESULT或PARTIAL_RESULT_MODE_UNSPECIFIED。請參閱「修改截斷行為」。
修改截斷行為
執行 SQL 時,您可以透過在要求中加入 "partialResultMode" 欄位,控管結果大小的處理方式。這個欄位接受下列值:
FAIL_PARTIAL_RESULT:預設值。如果結果超過 10 MB,或只能擷取部分結果,請擲回錯誤。請勿傳回結果。ALLOW_PARTIAL_RESULT:如果結果超過 10 MB,或因發生錯誤而只能擷取部分結果,請傳回截斷的結果,並將partial_result設為 true。請勿擲回錯誤。PARTIAL_RESULT_MODE_UNSPECIFIED:未指定模式,與FAIL_PARTIAL_RESULT相同。
限制
- 回應大小上限為 10 MB。如果
partialResultMode設為ALLOW_PARTIAL_RESULT,超過這個大小的結果會遭到截斷,否則系統會擲回錯誤。 - 要求大小上限為 0.5 MB。
- 您只能為正在執行的 SQL Server 適用的 Cloud SQL 執行個體執行 SQL 陳述式。
- 如果執行個體已設定為外部伺服器複製,Cloud SQL 就不支援搭配使用 Data API。
- 如果要求處理時間超過 30 秒,系統就會取消要求。系統不支援使用
SET LOCK_TIMEOUT設定較高的陳述式逾時時間。 為避免過載,Cloud SQL 會限制每個執行個體的並行
executeSql要求數量。如果達到上限,後續要求就會失敗,並傳回下列其中一個錯誤:At most 'x' concurrent queries may be run on this instance. Try again later.Maximum concurrent reads 'x' reached.
如果執行個體的總記憶體小於 10 GB,則上限 (
x) 為 5 個查詢;如果總記憶體至少有 10 GB,則上限為 10 個查詢。每個回應最多可包含 10 則資料庫訊息或警告。
如果陳述式語法或執行階段發生錯誤,系統就不會傳回任何結果。
Data API 無法以密碼空白的內建使用者身分進行驗證。
當執行個體正在進行特定維護作業時,為確保資料完整性,Data API 可能會暫時遭到封鎖。如果發生這種情況,請稍後再試。
- 系統不支援
GO指令。這個指令用於 Microsoft SQL Server 公用程式,表示陳述式批次已結束,可以傳送至 SQL Server。 如果查詢包含二進位資料欄,資料 API 就無法顯示。 請改為將二進位值轉換為字串。
舉例來說,請將:
SELECT my_binary_column from my_table2;替換為:
SELECT CONVERT(NVARCHAR(4000), my_binary_column, 1) from my_table2;執行多項查詢時,如果其中一項查詢失敗,系統會傳回第一個遇到的錯誤。錯誤發生前,批次中的部分陳述式可能已成功執行。您可以在
transaction陳述式中包裝多個查詢,避免發生這個問題:BEGIN TRANSACTION YOUR_SQL_STATEMENTS COMMIT;更改下列內容:
- YOUR_SQL_STATEMENTS:您要執行的陳述式,做為這項查詢的一部分
- SQL 指令碼及其執行回應可能會在用戶端與目標執行個體位置之間的中間位置傳輸。因此,對於某些 Assured Workloads 專案,以及手動強制執行
constraints/sql.restrictNoncompliantResourceCreation的專案,要求會失敗並顯示「not supported for instances in certain Assured Workloads control packages folders」錯誤。