使用 SQL 存储过程
存储过程是可以从其他查询或其他存储过程调用的语句集合。过程可以接受输入参数并返回值作为输出。您将过程命名并存储在 BigQuery 数据集中。多个用户可以使用一个存储过程访问或编辑多个数据集中的数据。它还可以包含多语句查询。
一些存储过程内置于 BigQuery 中,不需要创建。这称为“系统过程”,您可以在系统过程参考中详细了解它们。
存储过程支持过程语言语句,可让您执行定义变量和实现控制流等操作。如需详细了解过程语言语句,请参阅过程语言参考。
创建存储过程
如需创建过程,请使用 CREATE PROCEDURE
语句。
在以下概念性示例中,procedure_name
表示过程,过程正文位于 BEGIN
和 END
语句之间:
CREATE PROCEDURE dataset_name.procedure_name()
BEGIN
-- statements here
END
以下示例显示了一个包含多语句查询的过程。该多语句查询设置一个变量,运行 INSERT
语句,并将结果显示为格式化的文本字符串。
CREATE OR REPLACE PROCEDURE mydataset.create_customer()
BEGIN
DECLARE id STRING;
SET id = GENERATE_UUID();
INSERT INTO mydataset.customers (customer_id)
VALUES(id);
SELECT FORMAT("Created customer %s", id);
END
在上述示例中,过程名称是 mydataset.create_customer
,过程正文位于 BEGIN
和 END
语句之间。
要调用该过程,请使用 CALL
语句:
CALL mydataset.create_customer();
使用输入参数传入值
过程可以具有输入参数。输入参数允许过程输入,但不允许输出。
CREATE OR REPLACE PROCEDURE mydataset.create_customer(name STRING)
BEGIN
DECLARE id STRING;
SET id = GENERATE_UUID();
INSERT INTO mydataset.customers (customer_id, name)
VALUES(id, name);
SELECT FORMAT("Created customer %s (%s)", id, name);
END
使用输出参数传出值
过程可以包含输出参数。输出参数从过程返回值,但不允许向过程输入。如需创建输出参数,请在参数名称前使用 OUT
关键字。
例如,此版本的过程通过 id
参数返回新客户 ID:
CREATE OR REPLACE PROCEDURE mydataset.create_customer(name STRING, OUT id STRING)
BEGIN
SET id = GENERATE_UUID();
INSERT INTO mydataset.customers (customer_id, name)
VALUES(id, name);
SELECT FORMAT("Created customer %s (%s)", id, name);
END
要调用此过程,您必须使用变量接收输出值:
--- Create a new customer record.
DECLARE id STRING;
CALL mydataset.create_customer("alice",id);
--- Display the record.
SELECT * FROM mydataset.customers
WHERE customer_id = id;
使用输入/输出参数传入和传出值
过程还可以包含输入/输出参数。输入/输出参数会从过程返回值并接受对该过程的输入。如需创建输入/输出参数,请在参数名称前面使用 INOUT
关键字。如需了解详情,请参阅参数模式。
向例程授权
您可以将存储过程授权为例程。借助授权例程,您可以与特定用户或群组共享查询结果,而无需为其授予生成结果的底层表的访问权限。例如,已获授权的例程可以计算对数据的聚合,也可以查找表值并在计算中使用该值。
已获授权的例程可以创建、删除和操作表,以及针对底层表调用其他存储过程。
如需了解详情,请参阅已获授权的例程。
调用存储过程
如需在创建存储过程后对其进行调用,请使用 CALL
语句。例如,以下语句会调用存储过程 create_customer
:
CALL mydataset.create_customer();
调用系统过程
如需调用内置系统过程,请使用 CALL
语句。例如,以下语句调用系统过程 BQ.REFRESH_MATERIALIZED_VIEW
:
CALL BQ.REFRESH_MATERIALIZED_VIEW;