Docs /SQL Editor /Query parameters
SQL EditorQuerying

Query parameters

A comment at the top of the tab declares a typed parameter and its value. The editor types every @name, the run sends real BigQuery query parameters, and the values travel with the SQL in share links, history and git.

Query 1
123456
-- querylab:param start_date DATE = '2025-09-01'
-- querylab:param makes ARRAY<STRING> = ['FORD', 'VOLKSWAGEN']
SELECT make, COUNT(*) AS tests
FROM `ace-analytics.warehouse.fact_mot_test`
WHERE completed_date >= @start_date AND make IN UNNEST(@makes)
GROUP BY make

Declaring a parameter

One line per parameter, anywhere in the tab:

-- querylab:param <name> <type> = <value>
  • The type is any BigQuery parameter type, including ARRAY<…>, STRUCT<…>, RANGE<…> and INTERVAL. Type parameters are the one thing that isn’t allowed: a query parameter is a STRING, never a STRING(10).
  • The value is a GoogleSQL literal, checked against the type as you type. NULL is a valid value for any type, and [] is a real empty array.
  • Spacing and case of querylab:param don’t matter, and parameter names match the query case-insensitively, as they do in BigQuery. Declaring the same name twice is an error on the second line.

Typing -- opens completions for querylab:, then the directive name. After @ in the query, completions offer the declared names; after @person., the fields of a STRUCT parameter.

What the editor knows

A declared @name has the declared type everywhere Prism looks at the query: hover shows it, type checks use it, and a comparison against the wrong type is flagged like any other type mismatch.

An @name that no directive declares is an error, and the run is blocked with the same message:

123
SELECT make
FROM `ace-analytics.warehouse.fact_mot_test`
WHERE completed_date >= @start_date
Parameter @start_date has no value. Declare it with -- querylab:param start_date <type> = <value>.

The quick fix Declare parameter @start_date inserts the directive at the top of the tab. The type is prefilled when the query gives it away (completed_date >= @start_date makes it a DATE, IN UNNEST(@makes) an array, LIMIT @n an INT64); otherwise it is STRING = ''.

What happens at run time

Every run and every cost estimate sends the declared parameters as typed BigQuery query parameters (parameterMode: NAMED, with arrayType, structTypes and nested values where the type needs them). The directive lines stay in the SQL as comments, which BigQuery ignores.

Running a selection keeps the parameters: the directives the selection references are carried along, so a highlighted fragment runs like the whole tab.

Because the values live in the SQL, nothing is hidden in tab state. A share link, a history entry, a pasted snippet or a committed file carries its parameters with it.

Editing values from the status bar

Click the ⚙ at the left of the status bar. The Parameters section lists each declared parameter with its type, its line, and an editable value. Editing a value rewrites just that part of the directive line, as its own undo step. A value that comes from a Jinja template can’t be edited here; the panel says so and points you at the SQL.

Why not DECLARE?

DECLARE start_date DATE DEFAULT '2025-09-01'; works, but it turns the query into a multi-statement script, and that costs you three things:

  • A script’s results never come from BigQuery’s result cache, so repeat runs are billed again.
  • The estimate for a script is a lower bound, not the price of the run.
  • The SQL can’t be pasted into code that binds parameters; @start_date can, unchanged.

A parameter directive keeps the query a single statement and matches what your application sends in production.

Parameters in notebooks

A SQL cell can declare parameters with the same directive lines, and they flow to the cells below it, like notebook variables do. A cell lower in the notebook can redeclare a name to override the value from above. Plain assignments (name = 'x';) keep working and feed @name as a STRING; the editor offers Convert to typed parameter on assignments used that way.