适用于:
Databricks SQL Databricks Runtime 17.0 及更高版本,
Unity Catalog
在 Unity 目录中创建一个过程,该过程采用或修改参数、执行一组 SQL 语句,并选择性地返回结果集。
语法
CREATE [OR REPLACE] PROCEDURE [IF NOT EXISTS]
procedure_name ( [ procedure_parameter [, ...] ] )
[ characteristic [...] ]
AS compound_statement
procedure_parameter
[ IN | OUT | INOUT ] parameter_name data_type
[ DEFAULT default_expression ] [ COMMENT parameter_comment ]
characteristic
{ LANGUAGE SQL |
SQL SECURITY { INVOKER | DEFINER } |
NOT DETERMINISTIC |
COMMENT procedure_comment |
DEFAULT COLLATION default_collation_name |
MODIFIES SQL DATA }
参数
或替换
如果指定了名称,将替换具有相同名称的过程。 不能将现有函数替换为过程;这样做会引发 ROUTINE_ALREADY_EXISTS。 不能使用
IF NOT EXISTS;指定这两个参数引发 INVALID_SQL_SYNTAX。CREATE_ROUTINE_WITH_IF_NOT_EXISTS_AND_REPLACE。如果不存在
如果指定,则仅当具有该名称的过程尚不存在时,才创建过程。 如果存在同名的过程,则忽略该语句。 不能使用
OR REPLACE;指定这两个参数引发 INVALID_SQL_SYNTAX。CREATE_ROUTINE_WITH_IF_NOT_EXISTS_AND_REPLACE。-
程序的名称。 可以选择用架构名称来限定程序名称。 如果名称不限定,则会在当前架构中创建永久过程。
过程名称对于架构中的所有例程(过程和函数)必须是唯一的。 如果同名的例程存在且既不存在
OR REPLACE也不IF NOT EXISTS指定,则Azure Databricks引发ROUTINE_ALREADY_EXISTS。 procedure_parameter
指定过程的参数。
-
参数名称在过程中必须是唯一的;否则,Azure Databricks引发DUPLICATE_ROUTINE_PARAMETER_NAMES。
IN、 INOUT 或 OUT
(可选)描述参数的模式。
和
定义仅输入参数。 这是默认值。
INOUT
定义接受输入输出参数的参数。 如果过程完成时未处理错误,它将返回最终参数值作为输出。
外
定义输出参数。 该参数初始化为
NULL,如果过程完成且未处理错误,它将返回最终参数值作为输出。
-
支持的任何数据类型。
-
函数调用未向参数分配参数时使用的可选默认值。
default_expression必须可强制转换为data_type。 表达式不得引用另一个参数或包含子查询。为一个参数指定默认值时,以下所有参数也必须具有默认值。
DEFAULTOUT不支持或INOUT参数;指定引发PROCEDURE_CREATION_PARAMETER_OUT_INOUT_WITH_DEFAULT。 COMMENT 注释
参数的可选说明。
comment必须是STRING文本。
-
-
具有 SQL 过程定义的 SQL 复合语句 (
BEGIN ... END)。当创建过程时,将验证语法的正确性。 在调用过程之前,过程正文不会验证语义正确性。
特征
或
SQL SECURITY INVOKERSQL SECURITY DEFINER之一,并且LANGUAGE SQL是必需的。 所有其他选项都是可选的。 可以按任意顺序指定任意数量的特征,但只能指定每个子句一次。语言 SQL
函数实现的语言。
SQL SECURITY INVOKER
指定过程正文中的任何 SQL 语句将在调用该过程的用户的授权下执行。
在过程正文中解析关系和例程时,Azure Databricks在调用时使用当前目录和当前架构。
请参阅 授权用户和会话用户 ,了解授权用户和会话用户如何在过程主体内以及跨嵌套调用的行为。
SQL SECURITY DEFINER
适用于:
Databricks SQL指定过程主体中的任何 SQL 语句始终在过程的所有者(定义者)的授权下执行,而不考虑哪个用户调用该过程。 也就是说,所有者是正文 的授权用户 。 调用方只需要
EXECUTE对过程具有特权;对从正文引用的关系、例程和其他对象的所有访问检查都会根据授权的用户进行评估。在过程正文中解析关系和例程时,Azure Databricks使用创建过程时当前目录和架构。 调用方会话范围的对象(如临时视图、临时表、会话变量和会话范围函数)从正文中的解析搜索路径中排除,因此它们不能由其不限定的名称引用。 使用架构限定符引用
session时,它们仍可访问,例如session.object_name或system.session.object_name。无论调用程序的会话设置如何,SQL 配置(例如,
ANSI_MODE或影响正文中的语句语义的默认时区)也会在创建时捕获和使用。SQL SECURITY DEFINER在正文中,current_catalog返回创建过程时当前目录,current_schema和current_database返回创建过程时当前架构。SQL SECURITY DEFINER不会更改 session_user的值:它继续返回发出该CALL操作的用户。 请参阅 授权用户和会话用户 ,了解授权用户和会话用户在正文中的SQL SECURITY DEFINER区别。非确定性
假定过程是不确定的,这意味着它可以在每个调用上返回不同的结果,即使使用相同的参数调用它也是如此。
注释 procedure_comment
程序的备注。
procedure_comment必须是STRING文本。 默认值为NULL。DEFAULT COLLATION default_collation_name
适用于:
Databricks SQL
Databricks Runtime 17.1 及更高版本设置过程的默认排序规则。 过程的默认排序规则用作过程参数的默认排序规则、参数的表达式、
DEFAULTSTRING过程正文中声明的类型化局部变量以及STRING过程正文中使用的文本。在 Databricks Runtime 17.1 到 Databricks Runtime 18.2 中,
default_collation_name必须是UTF8_BINARY。 如果创建过程时所使用的架构具有非默认排序规则UTF8_BINARY,则此子句是必需的。适用于:
Databricks SQL
Databricks Runtime 18 及更高版本default_collation_name可以是任何受支持的 排序规则名称。如果未指定,则默认排序规则派生自创建该过程的架构。
修改 SQL 数据
假设有一个过程来修改 SQL 数据。
常见错误条件
- DUPLICATE_CLAUSES
- DUPLICATE_ROUTINE_PARAMETER_NAMES
- INVALID_DEFAULT_VALUE
- INVALID_SQL_SYNTAX。CREATE_ROUTINE_WITH_IF_NOT_EXISTS_AND_REPLACE
- MISSING_CLAUSES_FOR_OPERATION
- PROCEDURE_CREATION_EMPTY_ROUTINE
- PROCEDURE_CREATION_PARAMETER_OUT_INOUT_WITH_DEFAULT
- PROCEDURE_NOT_SUPPORTED
- PROCEDURE_NOT_SUPPORTED_WITH_HMS
- ROUTINE_ALREADY_EXISTS
- 不支持的过程排序规则
例子
-- Demonstrate INOUT and OUT parameter usage.
> CREATE OR REPLACE PROCEDURE add(x INT, y INT, OUT sum INT, INOUT total INT)
LANGUAGE SQL
SQL SECURITY INVOKER
COMMENT 'Add two numbers'
AS BEGIN
SET sum = x + y;
SET total = total + sum;
END;
> DECLARE sum INT;
> DECLARE total INT DEFAULT 0;
> CALL add(1, 2, sum, total);
> SELECT sum, total;
3 3
> CALL add(3, 4, sum, total);
7 10
-- The last executed query is the result set of a procedure
> CREATE PROCEDURE greeting(IN mode STRING COMMENT 'informal or formal')
LANGUAGE SQL
SQL SECURITY INVOKER
AS BEGIN
SELECT 'Hello!';
CASE mode WHEN 'informal' THEN SELECT 'Hi!';
WHEN 'formal' THEN SELECT 'Pleased to meet you.';
END CASE;
END;
> CALL greeting('informal');
Hi!
> CALL greeting('formal');
Pleased to meet you.
> CALL greeting('casual');
Hello!
-- Use SQL SECURITY DEFINER so the procedure runs with the owner's privileges
-- and references its creation-time catalog and schema. The invoker only needs
-- EXECUTE on `audit_app.ops.log_event`; they do not need any privileges on the
-- underlying `audit_app.private.audit_log` table.
> USE CATALOG audit_app;
> USE SCHEMA ops;
> CREATE OR REPLACE PROCEDURE log_event(IN event STRING)
LANGUAGE SQL
SQL SECURITY DEFINER
MODIFIES SQL DATA
AS BEGIN
INSERT INTO audit_app.private.audit_log
VALUES (current_user(), current_catalog(), current_schema(), event);
END;
-- Even when invoked from a different catalog/schema and by a different user,
-- the body still inserts into `audit_app.private.audit_log`, with
-- `current_catalog()` and `current_schema()` returning the values frozen at
-- creation time. `session_user()` is unaffected by `SQL SECURITY DEFINER`
-- and records the actual invoker -- which is what audit logs typically want.
> USE CATALOG sales;
> USE SCHEMA reports;
> CALL audit_app.ops.log_event('checkout_completed');