BigQuery stored procedures are named, parameter-driven SQL blocks you store in a dataset and call to run repeatable logic.
Stored procedures let you package multi-statement SQL—joins, DML, and conditionals—into a single, versioned object. Teams stop pasting long scripts in Slack and reuse one trusted procedure.
Use CREATE PROCEDURE with named parameters and declare the language as SQL. BigQuery automatically infers parameter modes as IN.
Use CALL dataset.proc_name(arg1, arg2);
.Procedures run in the project where they are stored, and you are billed only for resources consumed by statements inside the procedure.
Yes. You can SELECT from Customers
, INSERT into Orders
, or UPDATE Products
in the same procedure. Make sure the service account has the necessary dataset permissions.
Finish with a SELECT statement.The result set is returned just like a regular query so it can feed downstream dashboards or scripts.
• Prefix procedures with the team name, e.g., analytics.calculate_ltv
.
• Keep each procedure focused on one job.
• Store code in version control and deploy via CI.
• Use OR REPLACE
for zero-downtime updates.
Add DECLARE
variables and RAISE USING MESSAGE
statements, or call the procedure inside the BigQuery UI with the Execution Details panel open for per-statement timings.
Grant the bigquery.jobs.create
role to callers and use DEFINER
security options to run with the procedure owner’s permissions when necessary.
They live inside a dataset next to tables and views.Export them via bq show --format=prettyjson
for backups or migration.
Charges reflect the sum of bytes processed by all queries inside the procedure. Reading the same table twice counts twice, so refactor logic when costs spike.
Use scripts for ad-hoc exploration or one-off migrations. Convert to procedures once logic is stable and shared by more than one user or workflow.
.
Yes. Use the BigQueryInsertJobOperator
with a CALL
statement. The task waits until the procedure finishes.
BigQuery executes each DML statement atomically, but it does not support multi-statement transactional rollbacks. Design idempotent logic instead.
Export definitions with bq show --format=prettyjson
, store them in Git, and deploy via bq query --use_legacy_sql=false
in the target project.