本页面介绍了如何使用 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 来 创建 区域级 Secret 以存储密码。出于安全考虑,Data API 会在 API 请求中请求 Secret 的资源名称,而不是密码。区域级 Secret 应存储在与您的 Cloud SQL 实例相同的区域中。即使使用 Secret Manager 的全球 端点创建的 Secret 存储在同一区域中,也不受支持。
- 最佳实践是定义 IAM 条件,以允许用户访问特定 Secret,但不能访问项目中的其他 Secret。
所需的角色或权限
默认情况下,具有以下角色之一的用户或服务账号有权在 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)
您还可以为包含 cloudsql.instances.executesql
权限的用户或服务帐号定义 IAM 自定义角色
。IAM 自定义角色
支持此权限。
启用或停用 Data API
如需使用 Data API,您必须为每个实例启用该 API。 您可以随时停用 Data API。
控制台
-
在 Google Cloud 控制台中,前往 Cloud SQL 实例页面。
- 如需打开实例的概览页面,请点击实例名称。
- 从 SQL 导航菜单中选择连接。
- 点击网络 标签页。
- 选中允许 Data API 复选框。
- 点击保存 。
gcloud
如需在实例上启用 Data API 访问权限,请使用带有 --data-api-access=ALLOW_DATA_API 标志的 gcloud sql instances patch 命令:
gcloud sql instances patch INSTANCE_NAME --data-api-access=ALLOW_DATA_API
如需停用 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 存储在与 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 语句。如果语句包含空格或 Shell 特殊字符,则必须用英文引号引起来。
- USER:要以其身份进行身份验证的数据库用户。
- PASSWORD_SECRET_VERSION:Secret Manager Secret 的资源名称,其中包含数据库用户的密码。该 Secret 应为区域级 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 显示“应用完成!”消息。
- 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。
删除更改
删除 google_sql_provision_script 资源不会删除它创建的数据库内资源。如需删除这些资源,您可以在脚本中显式添加语句(例如 drop ... if exists),然后应用更改。
REST
如需使用 REST API 对实例上的数据库执行 SQL 语句,请向 executeSql 端点发送 POST 请求:
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 的资源名称,其中包含数据库用户的密码。该 Secret 应为区域级 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。 请参阅修改截断行为。
修改截断行为
您可以在请求中添加 "partialResultMode" 字段,以控制在执行 SQL 时如何处理大型结果。此字段接受以下值:
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。
- 您只能对正在运行的 Cloud SQL for SQL Server 实例运行 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。 如果查询包含二进制列,则 Data 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”。