# Database Lookup (Iterator)

> Find multiple rows from a database and iterate over each one.

- ID: `db_lookup_iterator`
- Type: Loop
- Category: [Databases](https://inventor.bot/docs/reference/blocks/databases.md)

- Loop block: write `for item := range db_lookup_iterator(Args{...}) { ... }` and read the current item's outputs from `item`. See loops.
- Database columns are extra inputs/outputs named `dbcol_<column name>`.

**Inputs**

| Name | Required | Description | Value |
| --- | --- | --- | --- |
| `database_id` | yes | Select the database to query. |  |
| `limit` |  | Maximum number of rows to return (default: 100, max: 1000). | e.g. `"100"` |
| `offset` |  | Number of rows to skip before returning results (default: 0). | e.g. `"0"` |
| `query_json` |  | Define filters to find rows. | JSON text, format below |
| `body` |  | Blocks to run for each row found. | blocks: `func() { ... }` |

**`query_json` format**: JSON text of type `DatabaseQuery`. Fields marked `?` are optional.

```ts
type DatabaseQuery = {
	where?: FilterGroup
	sort?: SortClause[]
	limit?: number
	offset?: number
}

type FilterGroup = {
	logic: string // "and" or "or"
	conditions: FilterCondition[]
}

type FilterCondition = {
	type: string // "comparison" or "group"
	columnId?: string // comparison only
	operator?: string // comparison only: eq, neq, gt, gte, lt, lte, contains, not_contains, starts_with, ends_with, is_empty, is_not_empty
	value?: string // comparison only
	group?: FilterGroup // group only
}

type SortClause = {
	columnId: string
	direction: string // "asc", "desc" or "random"
}
```

**Outputs**

| Name | Description | Value |
| --- | --- | --- |
| `iteration_number` | 0-based iteration index. | e.g. `"0"` |
| `total_iterations` | Total number of rows found. | e.g. `"10"` |
| `row_id` | The unique ID of the current row. | e.g. `"abc123xyz"` |
| `row_json` | The full row as a JSON object, including system fields (__id, __created_at, __updated_at, __created_at_unix, __updated_at_unix). | e.g. `"{\"__id\":\"abc123\",\"name\":\"example\"}"` |

**Example**

```go
for row := range db_lookup_iterator(Args{database_id: "..."}) {
	send_text_message(Args{channel_id: trigger.channel_id, message_content: "Row ID: " + row.row_id})
}
```