建立程序

適用於:勾選 是的 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;指定兩個 raise INVALID_SQL_SYNTAX。CREATE_ROUTINE_WITH_IF_NOT_EXISTS_AND_REPLACE

  • 若不存在

    若指定,僅在尚未存在該名稱的程序時建立程序。 如果具有相同名稱的程式存在,則會忽略 語句。 你無法用 OR REPLACE;指定兩個 raise INVALID_SQL_SYNTAX。CREATE_ROUTINE_WITH_IF_NOT_EXISTS_AND_REPLACE

  • procedure_name

    程序的名稱。 您可以選擇性地使用架構名稱來限定程式名稱。 如果名稱不合格,則會在目前的模式中建立永久程序。

    程序名稱必須是結構中所有例程(程序與函式)的唯一。 若存在同名例程且未OR REPLACE指定 nor,Azure Databricks IF NOT EXISTSROUTINE_ALREADY_EXISTS

  • procedure_parameter

    指定程序的參數。

    • parameter_name

      參數名稱必須在程序中唯一;否則Azure Databricks會加DUPLICATE_ROUTINE_PARAMETER_NAMES

    • ININOUTOUT

      選擇性地描述 參數的模式。

      • 定義為僅供輸入的參數。 這是預設值。

      • INOUT

        定義接受輸入輸出自變數的參數。 如果程式在沒有未處理的錯誤的情況下完成,則會將最終參數值當做輸出傳回。

      • 定義輸出參數。 參數會初始化為 NULL ,如果程式完成且沒有未處理的錯誤,則會將最終參數值當做輸出傳回。

    • 資料類型

      任何支援的數據類型。

    • 預設 default_expression

      當函式調用未將自變數指派給 參數時,要使用的選擇性預設值。 default_expression必須可被轉換為。 表達式不得參考另一個參數或包含子查詢。

      當您指定一個參數的預設值時,下列所有參數也必須有預設值。

      DEFAULT 不支援 OUTINOUT 參數;指定一個會產生 PROCEDURE_CREATION_PARAMETER_OUT_INOUT_WITH_DEFAULT

    • 批註comment

      參數的選擇性描述。 comment 必須是 STRING 文字表達式。

  • 複合語句

    具有 SQL 程式定義的 SQL 複合語句 (BEGIN ... END)。

    當程序建立時會驗證語法的正確性。 在程序被叫用之前,不會驗證程序主體的語意正確性。

  • 特徵

    其中一組 SQL SECURITY INVOKERSQL SECURITY DEFINERLANGUAGE SQL 且為必修。 所有其他專案都是選擇性的。 您可以依任何順序指定任意數目的特性,但只能指定每個子句一次。

    • 語言 SQL

      函式實作的語言。

    • SQL 安全性調用程式

      指定程式主體中的任何 SQL 語句都會在叫用程式的使用者授權下執行。

      在程序主體中解決關聯與例程時,Azure Databricks 使用目前的目錄與調用時的架構。

      請參閱 授權使用者與會話使用者 ,了解授權使用者與會話使用者在程序體內及巢狀呼叫間的行為。

    • SQL 安全定義器

      適用於:勾選「是」 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_name

      適用於:核取標示為是 Databricks SQL 核取標示為是 Databricks Runtime 17.1 和更新版本

      設定程序的預設排序。 程序的預設排序會作為程序參數、 DEFAULT 參數表達式、 STRING 程序主體中宣告的類型區域變數,以及 STRING 程序主體中使用的文字的預設整合。

      在 Databricks Runtime 17.1 到 Databricks Runtime 18.2 中, default_collation_name 必須是 UTF8_BINARY。 如果建立過程的架構具有預設定序與 UTF8_BINARY 不同,則此子句是必要的。

      適用於:勾選標記為是 Databricks SQL 勾選 Databricks 執行時間 18 LTS 及以上

      Note

      Databricks Runtime 18 比 Databricks Runtime 18.0、18.1 和 18.2 更新。 原本會以後期編號版本推出的功能,現在改為以 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');