# Bancos de dados e consultas

Um banco de dados é o artefato que [SQL Database](/pt-br/documentacao/plataforma/sql-database/) cria. Ele armazena dados relacionais e aceita SQL no dialeto do SQLite. Azion API v4 o endereça por um identificador inteiro e expõe cinco operações sobre ele: quatro no objeto de banco de dados e uma que executa statements SQL sobre o conteúdo dele. Esta página lista os campos de um banco de dados, as cinco operações, o resultado que um statement retorna e os erros que a API e os statements retornam.

---

## Nomes de banco de dados

O nome de um banco de dados é escolhido na criação e não pode ser alterado depois.

| Regra       | Valor                               |
| ----------- | ----------------------------------- |
| Comprimento | 6 a 50 caracteres                   |
| Caracteres  | Letras, números e o hífen (`-`)     |
| Unicidade   | Um nome é único dentro da sua conta |

Um nome fora desses limites retorna `14000`, com `10048` junto quando o nome tem menos de 6 caracteres. Um nome que a conta já tem retorna `14001`. Como o nome é fixo por toda a vida do banco de dados, um nome que registra o que o banco de dados armazena continua legível, como em `orders-eu`.

---

## Campos do banco de dados

| Campo             | Tipo                                | Obrigatório | Padrão     | Descrição                                                       |
| ----------------- | ----------------------------------- | ----------- | ---------- | --------------------------------------------------------------- |
| `id`              | integer                             | —           | —          | O identificador do banco de dados. Somente leitura              |
| `name`            | string, 6 a 50 caracteres           | Sim         | —          | O nome do banco de dados. Somente leitura após a criação        |
| `status`          | `creating`, `created` ou `deleting` | —           | `creating` | Estado de provisionamento. Somente leitura                      |
| `active`          | boolean                             | —           | `true`     | Indica se o banco de dados está ativo. Aceito apenas na criação |
| `last_modified`   | date-time                           | —           | —          | Quando o banco de dados mudou pela última vez. Somente leitura  |
| `last_editor`     | string                              | —           | —          | A conta que o alterou pela última vez. Somente leitura          |
| `product_version` | string                              | —           | `1.0`      | A versão do schema. Somente leitura                             |

Uma requisição de criação aceita `name` e `active`, e nada mais. Nenhum campo é editável depois: `PATCH` e `PUT` retornam `10007` `Method Not Allowed`, então um banco de dados nunca é renomeado e `active` nunca é alterado.

---

## Operações

Toda operação é autenticada e fica sob `https://api.azion.com/v4/workspace/sql`.

| Operação                    | Método e caminho                      |
| --------------------------- | ------------------------------------- |
| Listar bancos de dados      | `GET /databases`                      |
| Criar um banco de dados     | `POST /databases`                     |
| Recuperar um banco de dados | `GET /databases/{database_id}`        |
| Excluir um banco de dados   | `DELETE /databases/{database_id}`     |
| Executar uma consulta       | `POST /databases/{database_id}/query` |

As quatro operações de banco de dados agem sobre o objeto da tabela acima. A operação de consulta vai além dele, até as tabelas e linhas que o banco de dados contém.

### Criar um banco de dados

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/sql/databases \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "my-database"
}'
```

A resposta carrega `202` e o banco de dados que está sendo provisionado:

```json
{
  "state": "pending",
  "data": {
    "id": 1234,
    "name": "my-database",
    "status": "creating",
    "active": true,
    "last_modified": "2026-01-01T12:00:00.433088Z",
    "last_editor": "user@example.com",
    "product_version": "1.0"
  }
}
```

O `state` do envelope e o `status` do banco de dados são dois campos diferentes. `state` descreve a requisição, e `pending` significa que a plataforma a aceitou. `status` descreve o banco de dados, e `creating` significa que ele ainda não aceita consultas.

### Recuperar um banco de dados

```bash
curl --request GET \
  --url https://api.azion.com/v4/workspace/sql/databases/1234 \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]'
```

A resposta carrega `200` e nenhuma chave `state`:

```json
{
  "data": {
    "id": 1234,
    "name": "my-database",
    "status": "created",
    "active": true,
    "last_modified": "2026-01-01T12:00:24.058568Z",
    "last_editor": "user@example.com",
    "product_version": "1.0"
  }
}
```

O provisionamento leva cerca de 15 segundos. Consulte esta operação repetidamente após uma requisição de criação até que `status` seja `created`, e envie a primeira consulta então. Um identificador que não pertence a nenhum banco de dados retorna `10004`.

### Listar bancos de dados

```bash
curl --request GET \
  --url 'https://api.azion.com/v4/workspace/sql/databases?page_size=10' \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]'
```

A resposta carrega `200`, um banco de dados por entrada em `results` e os campos de paginação ao redor deles:

```json
{
  "count": 1,
  "total_pages": 1,
  "page": 1,
  "page_size": 10,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 1234,
      "name": "my-database",
      "status": "created",
      "active": true,
      "last_modified": "2026-01-01T12:00:24.058568Z",
      "last_editor": "user@example.com",
      "product_version": "1.0"
    }
  ]
}
```

| Campo              | O que carrega                                                                                      |
| ------------------ | -------------------------------------------------------------------------------------------------- |
| `count`            | Bancos de dados da conta que correspondem à requisição                                             |
| `total_pages`      | Páginas em que o resultado se divide, no `page_size` atual                                         |
| `page`             | A página que esta resposta carrega                                                                 |
| `page_size`        | Bancos de dados por página                                                                         |
| `next`, `previous` | As páginas adjacentes, ou `null` em cada extremidade                                               |
| `results`          | Um objeto de banco de dados por entrada, carregando os campos listados em Campos do banco de dados |

Quatro parâmetros de consulta restringem e ordenam a lista:

| Parâmetro de consulta | Efeito                                                                                   |
| --------------------- | ---------------------------------------------------------------------------------------- |
| `page`                | Retorna uma página da lista                                                              |
| `page_size`           | Bancos de dados por página. Padrão 10 e aceita até 100                                   |
| `search`              | Corresponde a parte de um nome de banco de dados                                         |
| `ordering`            | Ordena os resultados por um nome de campo. Prefixe o nome com `-` para ordem decrescente |

Um `page_size` acima de 100 retorna `10097`. Leia uma lista mais longa uma página por vez, com `page`.

### Excluir um banco de dados

```bash
curl --request DELETE \
  --url https://api.azion.com/v4/workspace/sql/databases/1234 \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]'
```

A resposta carrega `202` e `{"state": "pending"}`, e o banco de dados responde `10004` em segundos. Uma exclusão é aceita enquanto o status ainda é `creating`. A exclusão é permanente, e as linhas que o banco de dados continha não podem ser recuperadas.

### Executar uma consulta

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/sql/databases/1234/query \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "statements": ["SELECT id, name, email FROM users;"]
}'
```

A resposta carrega `200` e uma entrada por statement:

```json
{
  "state": "executed",
  "data": [
    {
      "results": {
        "columns": ["id", "name", "email"],
        "rows": [[1, "Ada", "ada@example.com"]],
        "rows_read": 1,
        "rows_written": 0,
        "query_duration_ms": 0.034
      }
    }
  ]
}
```

---

## Consulta

O corpo da consulta carrega uma chave, `statements`, que contém um array de strings SQL. Cada statement retorna uma entrada em `data`, na ordem em que o array os lista. Os dois statements abaixo criam uma tabela e a leem de volta:

```sql
CREATE TABLE IF NOT EXISTS cities (id INTEGER, city TEXT, country TEXT);
SELECT city, country FROM cities;
```

Cada um é uma string no array:

```json
{
  "statements": [
    "CREATE TABLE IF NOT EXISTS cities (id INTEGER, city TEXT, country TEXT);",
    "SELECT city, country FROM cities;"
  ]
}
```

Um statement bem-sucedido carrega um objeto `results` com cinco campos.

| Campo               | O que carrega                                                                                  |
| ------------------- | ---------------------------------------------------------------------------------------------- |
| `columns`           | Os nomes das colunas do conjunto de resultados. Vazio para um statement que não retorna linhas |
| `rows`              | Um array por linha, com os valores na ordem das colunas                                        |
| `rows_read`         | As linhas que o statement leu                                                                  |
| `rows_written`      | As linhas que o statement escreveu                                                             |
| `query_duration_ms` | Por quanto tempo o statement executou, em milissegundos                                        |

`rows_read` e `rows_written` são as duas métricas pelas quais SQL Database é cobrado, e a API as retorna para todo statement. Para o uso que cada plano inclui, consulte [Limites do SQL Database](/pt-br/documentacao/plataforma/sql-database/limites/).

Um array `statements` vazio retorna `200` com `"data": []`. Uma única chamada carregando 100 statements é bem-sucedida. Os statements em si são o SQL do SQLite: para a sintaxe que cada um aceita, consulte a [referência da linguagem SQLite](https://www.sqlite.org/lang.html).

---

## Statements com falha

Um statement que falha não faz a requisição falhar. A chamada retorna HTTP `200`, e a entrada desse statement carrega `error` no lugar de `results`:

```json
{
  "state": "executed",
  "data": [
    {
      "error": "no such table: nope"
    }
  ]
}
```

Um cliente que lê apenas o status HTTP trata essa resposta como um sucesso. Ele então lê uma chave `results` que não está lá. Verifique `data[].error` em toda entrada antes de ler `data[].results`, e reporte uma entrada que carrega `error` como um statement com falha.

Quando os statements não podem ser executados de forma alguma, a requisição retorna `422` com `14005` `Execute SQL Exception`, e `meta.database_name` nomeia o banco de dados. As duas rejeições são, portanto, lidas em dois lugares diferentes: um `422` no array `errors`, e um statement com falha dentro de um `200`.

---

## Autenticação

Toda requisição carrega um [personal token](/pt-br/documentacao/guias/plataforma/conta-e-billing/personal-tokens/) e pede JSON:

```http
Authorization: Token [TOKEN VALUE]
Accept: application/json
```

Uma requisição que carrega um corpo também carrega `Content-Type: application/json`.

A conta precisa das permissões de SQL Database para a operação. **View SQL Database** concede permissão para visualizar os bancos de dados criados e seus dados por meio da Azion API. **Edit SQL Database** concede permissão para criar e editar bancos de dados e seus dados por meio da Azion API. Para mais informações, consulte [Teams Permissions](/pt-br/documentacao/fundamentos/teams-permissions/).

---

## Erros

Uma requisição rejeitada carrega um array `errors`. Cada entrada nomeia o `code`, o `title`, um `detail`, o `status` e o campo ao qual se aplica em `source.pointer`.

```json
{
  "errors": [
    {
      "code": "14001",
      "title": "Name Already In Use.",
      "detail": "The database name already exists.",
      "status": "400",
      "source": {
        "pointer": "/data/name"
      }
    }
  ]
}
```

| Código  | Título                         | Status | Causa                                                                                                                |
| ------- | ------------------------------ | ------ | -------------------------------------------------------------------------------------------------------------------- |
| `10004` | `Not Found`                    | 404    | Nenhum banco de dados carrega esse identificador                                                                     |
| `10007` | `Method Not Allowed`           | 405    | Uma requisição `PATCH` ou `PUT` em um banco de dados                                                                 |
| `10048` | `Min Length`                   | 400    | O nome tem menos de 6 caracteres. Retornado junto com `14000`                                                        |
| `10059` | `Required Field`               | 400    | O corpo da consulta não carrega a chave `statements`. `source.pointer` é `/data/statements`                          |
| `10097` | `Invalid Page Size`            | 400    | `page_size` está acima de 100                                                                                        |
| `14000` | `Invalid Database Name Format` | 400    | O nome tem menos de 6 ou mais de 50 caracteres, ou carrega um caractere que não seja uma letra, um número ou o hífen |
| `14001` | `Name Already In Use.`         | 400    | A conta já tem um banco de dados com esse nome                                                                       |
| `14005` | `Execute SQL Exception`        | 422    | Os statements não puderam ser executados. `meta.database_name` nomeia o banco de dados                               |

Um statement que falha retorna seu erro como uma string dentro de um `200`, e nunca em um array `errors`.

| String de erro                    | Causa                                                    |
| --------------------------------- | -------------------------------------------------------- |
| `no such table: <name>`           | O statement nomeia uma tabela que não existe             |
| `too many columns on <table>`     | O statement `CREATE TABLE` declara mais de 2.000 colunas |
| `vector: max size exceeded 65536` | `vector()` recebeu mais de 65.536 dimensões              |

Para os tipos vetoriais e as funções que os constroem e comparam, consulte [SQL Database Vector Search](/pt-br/documentacao/plataforma/sql-database/vector-search/).

---

## Limites

Um nome de banco de dados tem de 6 a 50 caracteres, uma tabela comporta até 2.000 colunas e uma resposta de listagem retorna até 100 bancos de dados. Todo limite de um banco de dados, o que a plataforma faz além de cada valor e o uso que cada plano inclui estão em [Limites do SQL Database](/pt-br/documentacao/plataforma/sql-database/limites/).

---

## A API do runtime

As operações acima são chamadas HTTP, endereçadas a `api.azion.com` e autenticadas com um personal token. Uma function em execução no Azion Runtime alcança o mesmo banco de dados por um segundo caminho: ela importa o módulo `azion:sql` e chama `Database.open`, que recebe o nome do banco de dados, não carrega token e abre uma conexão com a réplica de leitura.

Esse módulo pertence ao runtime, e não a SQL Database, então seus objetos de conexão, statement e linha são documentados junto com os outros bindings do runtime, em [SQL Database API](/pt-br/documentacao/devtools/runtime/api-reference/sql-database/).

---

## A biblioteca azion

O pacote npm `azion` exporta `azion/sql`, que encapsula as mesmas operações para Node e TypeScript. Ele lê o token da variável de ambiente `AZION_TOKEN`.

A biblioteca não é um passthrough, e duas diferenças mudam o que você pode ler dela. Ela converte os campos do banco de dados para camelCase: `lastModified`, `lastEditor` e `productVersion`. O resultado de consulta dela descarta `rows_read`, `rows_written` e `query_duration_ms`, então uma conta que mede o próprio consumo lê esses três da API, e não da biblioteca. Para as funções que a biblioteca exporta, consulte [Biblioteca SQL da Azion](/pt-br/documentacao/devtools/azion-lib/sql/).

---

## Recursos relacionados

- [Como o SQL Database funciona](/pt-br/documentacao/plataforma/sql-database/como-funciona.md): Onde um banco de dados é escrito, onde ele é lido e o que chega até ele.
- [Limites do SQL Database](/pt-br/documentacao/plataforma/sql-database/limites.md): Todo limite desta página em uma tabela, com o uso que cada plano inclui.
- [Crie e gerencie bancos de dados](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/gerenciar-bancos-dados-edge-sql.md): O procedimento por trás das quatro operações de banco de dados, pelo Azion Console e pela API.
- [Crie tabelas e consulte dados](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/criar-tabelas-edge-sql.md): O procedimento por trás da operação de consulta, com a saída que cada statement retorna.
- [Vector search](/pt-br/documentacao/plataforma/sql-database/vector-search.md): Os tipos de coluna vetoriais, as funções de distância e o índice de que precisam.
- [SQL Database API](/pt-br/documentacao/devtools/runtime/api-reference/sql-database.md): Ler o mesmo banco de dados de uma function, com `azion:sql`.
