Guides

Run Saved Queries

Save SQL once and run it by name with checked command-line arguments.

Use a saved query when several agents or reports need the same read. Silo stores the SQL and its parameter types in the local database. For a one-off question, use silo sql instead.

Define and run a named query

This example uses the issues table and row from Getting started. It finds titles that start with the supplied text. Save this definition as find-issues.json:

{
  "name": "find-issues",
  "description": "Issues whose titles start with a supplied prefix.",
  "sql": "SELECT id, title FROM issues WHERE title LIKE :prefix || '%' ORDER BY title",
  "parameters": [
    {
      "name": "prefix",
      "type": "text",
      "description": "Title prefix to search for using SQLite LIKE."
    }
  ]
}

Save the definition, then invoke it by its name:

silo query put --file find-issues.json
silo query find-issues --prefix Document

The result should include Document the release process. The query uses SQLite LIKE: ASCII letters match without regard to case, and % and _ in the input act as wildcards.

Saving the definition changes the database. Running it only reads current rows and does not create pending synchronization work.

Choose a parameter style

Named parameters are the default and make each value self-describing. Each declaration becomes a hyphenated CLI option, while SQL uses the original underscore name. For example, minimum_revision becomes --minimum-revision.

Use positional parameters when the order is easy to remember, such as a single row limit. Save this definition as list-issues.json:

{
  "name": "list-issues",
  "description": "The first N issues in title order.",
  "parameter_style": "positional",
  "sql": "SELECT id, title FROM issues ORDER BY title LIMIT ?1",
  "parameters": [
    {
      "name": "limit",
      "type": "integer/positive",
      "description": "Maximum number of issues to return.",
      "default": 20
    }
  ]
}

Save it and run it without a limit to use the default of 20:

silo query put --file list-issues.json
silo query list-issues

The result contains up to 20 issues in title order. Run silo query list-issues 5 to request at most five.

Positional SQL may use one anonymous ? per declaration or every numbered placeholder from ?1 through ?N. Do not mix the forms. Once one positional parameter has a default, every later parameter must also have a default.

Treat parameters as a typed contract

Each parameter uses a registered semantic type. Silo converts the CLI input to that type, checks it, and binds it as a SQLite value. It does not build SQL by inserting the value into the query text.

A parameter without default is required. Run query-specific help to see the generated interface:

silo query find-issues --help

Query limits:

  • One read-only SQL statement that returns columns
  • No access to Silo or SQLite internal objects
  • At most 500 result rows, with truncation marked in the output

Add ORDER BY when result order matters.

Reuse a query in a report

After saving find-issues, a report script can call it with the same parameter. This script body returns a Markdown table or an empty-result message:

const issues = silo.query('find-issues', { prefix: 'Document' })

return issues.rows.length ? markdown.table(issues) : '_No matching issues._'

Named parameters use an object; positional parameters use an array in declaration order. Omit parameters only when the saved query has no required inputs.

Each refresh uses the current query definition. Changing or deleting it can break a report; Silo does not scan scripts to find their query dependencies. If refresh fails, the last successful rendering stays available. See Publish a refreshable report to save and open a report.

Inspect and manage definitions

Command Result
silo query put Creates or atomically replaces a definition.
silo query list Lists definitions, parameter styles, and update times.
silo query show <name> Shows SQL, parameter types, defaults, and descriptions.
silo query delete <name> Permanently deletes a definition not referenced by a legacy report.
silo query <name> Runs the saved SQL without changing data.

The names put, list, show, and delete are reserved so direct query invocation remains unambiguous.

When synchronization is configured, saved-query changes remain local until silo push. Running a query does not change or synchronize data.