> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> 了解为何 `SET ROLE` 在 ClickHouse Cloud SQL 控制台中不会持久生效，以及如何为每位用户分配持久权限。

# 为何 `SET ROLE` 不会在 ClickHouse Cloud SQL 控制台中持久生效

当您在 ClickHouse Cloud SQL 控制台中运行 `SET ROLE` 时，角色似乎会在单次查询中更改，但在下一次查询时又恢复原状。如果权限需要跨查询和会话持续生效，请设置用户专属 SQL 控制台角色。

<div id="symptoms">
  ## 症状
</div>

您可能会遇到以下一种或多种情况：

* 运行 `SET ROLE sql_console_developer` 后，后续查询仍使用 `sql_console_read_only`。
* `currentRoles`、`enabledRoles` 和 `defaultRoles` 的结果因查询而异。
* 同时运行 `SET ROLE` 和另一条查询时，无法始终保留所选角色。
* `SHOW GRANTS` 列出了预期角色，但其权限未生效。

您可以通过以下方式查看当前用户和角色：

```sql theme={null}
SELECT
    currentUser(),
    currentRoles(),
    enabledRoles(),
    defaultRoles();
```

<div id="why-this-happens">
  ## 为什么会出现这种情况
</div>

SQL 控制台通过无状态 HTTP 连接向多副本 ClickHouse Cloud 服务发送查询。连续执行的查询不一定会使用同一连接或副本。

`SET ROLE` 会更改当前会话中启用的角色，但不会将该会话状态保留到后续的 SQL 控制台请求中。因此，后续查询可能不会使用先前请求启用的角色运行。

因此，请勿将 `SET ROLE` 用作 SQL 控制台中的持久性访问控制机制。

<div id="how-sql-console-user-roles-work">
  ## SQL 控制台用户角色的工作原理
</div>

当用户打开 SQL 控制台时，ClickHouse Cloud 会按以下命名规则创建一个数据库用户：

```text theme={null}
sql-console:user@example.com
```

ClickHouse Cloud 还会检查名称符合以下约定的数据库角色：

```text theme={null}
sql-console-role:user@example.com
```

当该角色存在时，ClickHouse Cloud 会将其分配给相应的 SQL 控制台用户。这是向单个 SQL 控制台用户授予持久性自定义权限的受支持方式。

| 实体                                            | 用途                    | 持久性                     |
| --------------------------------------------- | --------------------- | ----------------------- |
| `sql-console:<email>`                         | 用户打开 SQL 控制台时预配的数据库用户 | 是，由 ClickHouse Cloud 管理 |
| `sql_console_admin` 和 `sql_console_read_only` | 内置 SQL 控制台角色          | 是，由 ClickHouse Cloud 管理 |
| `sql-console-role:<email>`                    | 管理员创建的用户专属自定义角色       | 是，用户登录时应用               |

<div id="configure-persistent-permissions">
  ## 配置持久权限
</div>

请使用在该服务上具有管理特权的用户运行以下语句，例如具有 `sql_console_admin` 角色的 SQL 控制台用户，或拥有 `ACCESS MANAGEMENT` 特权的其他用户。

<Steps>
  <Step title="创建自定义角色" id="create-the-custom-role">
    以下示例创建自定义 `sql_console_developer` 角色，并授予其对 `my_database` 的权限：

    ```sql theme={null}
    CREATE ROLE IF NOT EXISTS sql_console_developer;

    GRANT SELECT, INSERT, CREATE TABLE
    ON my_database.*
    TO sql_console_developer;
    ```

    `sql_console_developer` 是示例角色，并非 ClickHouse Cloud 内置角色。您也可以使用现有的自定义角色，只要该角色具备用户所需的权限即可。
  </Step>

  <Step title="创建用户专属 SQL 控制台角色" id="create-the-per-user-sql-console-role">
    创建一个名称中包含用户完整电子邮件地址的角色：

    ```sql theme={null}
    CREATE ROLE IF NOT EXISTS `sql-console-role:user@example.com`;
    ```

    由于角色名称中包含特殊字符，必须使用反引号。
  </Step>

  <Step title="授予自定义角色" id="grant-the-custom-role">
    将所需角色授予用户专属 SQL 控制台角色：

    ```sql theme={null}
    GRANT sql_console_developer
    TO `sql-console-role:user@example.com`;
    ```

    如有需要，可以授予多个角色：

    ```sql theme={null}
    GRANT sql_console_developer, sql_console_read_only
    TO `sql-console-role:user@example.com`;
    ```
  </Step>

  <Step title="启动新的 SQL 控制台会话" id="start-a-new-sql-console-session">
    请用户退出 SQL 控制台后重新登录，或刷新浏览器选项卡。在新会话中，ClickHouse Cloud 会将 `sql-console-role:user@example.com` 应用于 `sql-console:user@example.com`；无需执行 `SET ROLE` 语句。

    验证已启用角色：

    ```sql theme={null}
    SELECT
        currentUser(),
        currentRoles(),
        enabledRoles(),
        defaultRoles();
    ```

    结果中应包含通过 `sql-console-role:user@example.com` 授予的权限。
  </Step>
</Steps>

<div id="avoid-modifying-managed-roles">
  ## 避免修改托管角色
</div>

请勿修改 `sql_console_admin` 或 `sql_console_read_only` 来授予自定义权限。这些内置角色由 ClickHouse Cloud 管理。若要为单个用户设置权限，请使用 `sql-console-role:<email>`。

有关角色管理的一般示例，请参阅[常见访问管理查询](/docs/zh/products/cloud/guides/security/cloud-access-management/common-access-management-queries)。
