创建流程

适用于:勾选为“是”的 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

  • procedure_name

    程序的名称。 可以选择用架构名称来限定程序名称。 如果名称不限定,则会在当前架构中创建永久过程。

    过程名称对于架构中的所有例程(过程和函数)必须是唯一的。 如果同名的例程存在且既不存在OR REPLACE也不IF NOT EXISTS指定,则Azure Databricks引发ROUTINE_ALREADY_EXISTS

  • procedure_parameter

    指定过程的参数。

    • parameter_name

      参数名称在过程中必须是唯一的;否则,Azure Databricks引发DUPLICATE_ROUTINE_PARAMETER_NAMES

    • ININOUTOUT

      (可选)描述参数的模式。

      • 定义仅输入参数。 这是默认值。

      • INOUT

        定义接受输入输出参数的参数。 如果过程完成时未处理错误,它将返回最终参数值作为输出。

      • 定义输出参数。 该参数初始化为 NULL ,如果过程完成且未处理错误,它将返回最终参数值作为输出。

    • 数据类型

      支持的任何数据类型。

    • 默认 default_expression

      函数调用未向参数分配参数时使用的可选默认值。 default_expression 必须可强制转换data_type。 表达式不得引用另一个参数或包含子查询。

      为一个参数指定默认值时,以下所有参数也必须具有默认值。

      DEFAULT OUT不支持或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_namesystem.session.object_name

      无论调用程序的会话设置如何,SQL 配置(例如, ANSI_MODE 或影响正文中的语句语义的默认时区)也会在创建时捕获和使用。

      SQL SECURITY DEFINER在正文中,current_catalog返回创建过程时当前目录,current_schemacurrent_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 数据。

常见错误条件

例子

-- 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');