---
name: metabase_execute_query
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func MetabaseExecuteQuery(client MetabaseClient, databaseID int, sql string, maxResults int) (map[string]any, error)"
description: "Ejecuta una query SQL ad-hoc contra una database de Metabase sin guardarla como card. Util para consultas rapidas y exploracion. Endpoint: POST /api/dataset."
tags: [metabase, query, execute, sql, dataset, api]
uses_functions: []
uses_types: [MetabaseClient_go_infra]
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [fmt]
params:
  - name: client
    desc: "cliente MetabaseClient autenticado"
  - name: databaseID
    desc: "ID de la database en Metabase"
  - name: sql
    desc: "query SQL a ejecutar"
  - name: maxResults
    desc: "limite de filas (0 = default 2000)"
output: "mapa con status, row_count, running_time, data.columns, data.rows"
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/metabase_execute_query.go"
---

## Ejemplo

```go
// Query simple
result, err := MetabaseExecuteQuery(client, 1, "SELECT * FROM users LIMIT 10", 0)
if err != nil {
    log.Fatal(err)
}
data := result["data"].(map[string]any)
rows := data["rows"].([]any)

// Query con limite custom
result, err := MetabaseExecuteQuery(client, 1, "SELECT * FROM orders", 5000)
```

## Notas

### Parametros para un LLM

| Parametro | Tipo | Requerido | Descripcion |
|-----------|------|-----------|-------------|
| client | MetabaseClient | si | Cliente autenticado |
| databaseID | int | si | ID de la database en Metabase (obtener con GET /api/database) |
| sql | string | si | Query SQL a ejecutar |
| maxResults | int | no | Limite de filas. 0 = default 2000 |

### Diferencia con MetabaseExecuteCard

- `MetabaseExecuteQuery`: query ad-hoc, no se guarda. Usa POST /api/dataset.
- `MetabaseExecuteCard`: ejecuta una card ya guardada. Usa POST /api/card/:id/query.

Usar esta funcion para exploracion rapida. Si la query se va a reutilizar, crear una card con MetabaseCreateCard.

### Estructura de la respuesta

Misma estructura que MetabaseExecuteCard:
- `data.columns`: nombres de columnas
- `data.rows`: filas de datos
- `row_count`: numero de filas
- `running_time`: tiempo en ms
- `status`: "completed" o "failed"
