翻譯:CREATE FUNCTION語句(已提交到MariaDB官方手冊)

来源:https://www.cnblogs.com/f-ck-need-u/archive/2018/04/02/8698943.html
-Advertisement-
Play Games

本文為mariadb官方手冊:CREATE FUNCTION的譯文。 原文:https://mariadb.com/kb/en/library/create-function/我提交到MariaDB官方手冊的譯文:https://mariadb.com/kb/zh-cn/create-functio ...


本文為mariadb官方手冊:CREATE FUNCTION的譯文。

原文:https://mariadb.com/kb/en/library/create-function/
我提交到MariaDB官方手冊的譯文:https://mariadb.com/kb/zh-cn/create-function/

語法

CREATE [OR REPLACE]
    [DEFINER = {user | CURRENT_USER | role | CURRENT_ROLE }]
    [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...]
    RETURN func_body

func_parameter:
    param_name type

type:
    Any valid MariaDB data type

characteristic:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'

func_body:
    Valid SQL procedure statement

描述

可以使用CREATE FUNCTION語句創建一個新的存儲函數stored function。要使用CREATE FUNCTION語句,必須要具備CREATE ROUTINE許可權。

函數可以定義任意數量的參數,在函數體(func_body)部分會返回一個值。函數體部分可以是任意有效的SQL表達式,例如某些select語句。如果你有合適的許可權,你完全可以像調用內置函數一樣調用存儲函數。關於許可權的詳細信息,見下文:Security

此外,你也可以使用CREATE FUNCTION語句的變體格式來安裝一個用戶自定義函數(UDF)。關於UDF,詳細信息見:CREATE FUNCTION (UDF)

你可以使用一個圓括弧包圍SELECT作為func_body部分,正如使用子查詢一樣。但註意,SELECT語句必須返回單個值(標量值,即單行且單列的值)。調用函數時,如果SELECT語句返回了多列,則報1241的錯誤,如果SELECT語句返回了多行,則報1242的錯誤。為了保險,可以使用LIMIT子句保證只返回單行數據。

你可以使用BEGIN...END語句塊替換這裡的RETURN子句,但是在語句塊中,必須要包含一個RETURN語句。當調用函數時,執行到RETURN子句時將立即返回其結果,在RETURN子句之後的語句都不會再執行。

預設情況下,函數是關聯到預設資料庫上的。如果要將函數顯式關聯到一個指定的資料庫,可以在創建時使用全稱db_name.func_name。如果創建的存儲函數名和內置的函數名同名,則必須使用全稱來調用它。

定義存儲函數時,參數列表可以為空。如果指定參數名,則參數名不區分大小寫。

每個參數都可以聲明為任意有效的數據類型,但無法使用COLLATE屬性。

>RETURNS子句

RETURNS子句指定函數的返回類型。可以使用NULL值來表示返回任意有效數據類型。

如果RETURN子句的返回值類型和此處定義的數據類型不一致會如何?這取決於創建函數的時候,SQL_MODE的影響行為。

如果SQL_MODE為strict模式的值(即指定了STRICT_ALL_TABLES或STRICT_TRANS_TABLES),將報1366錯誤。

除這種情況,如果返回值類型不一致,則返回值將被強制轉換為指定的數據類型。例如,RETURNS子句指定返回一個ENUM或SET數據類型,但RETURN子句返回了一個整型,則返回值將強制轉換為ENUM或SET成員對應的字元串(譯者註:雖然ENUM允許存儲數值,但強烈建議不要存儲數值,因為非常容易混淆ENUM的索引值和實際存儲的數值,因此這裡直接說是字元串)。

MariaDB將在創建routine的時候保留系統變數SQL_MODE的值,以後任何時間調用routine時都使用該SQL_MODE值,而不管當前調用routine時的SQL MODE值是什麼。

>LANGUAGE SQL

LANGUAGE SQL代表的是一個標準的SQL子句,它是為了移植性而存在的。但是,該子句在MariaDB中沒有任何意義,因為MariaDB的存儲函數中唯一支持的語言只有SQL。

>OR REPLACE

如果使用了OR REPLACE子句,它的行為等價於:

DROP FUNCTION IF EXISTS function_name;
CREATE FUNCTION function_name ...;

但不會刪除該函數已有的許可權privileges。

>IF NOT EXISTS

如果使用 IF NOT EXISTS 子句,那麼當函數存在時,MariaDB將返回一個warning信息而不是直接返回錯誤。IF NOT EXISTS不能和OR REPLACE一起使用。

>[NOT] DETERMINISTIC

如果函數根據給定的參數列表能夠返回一個確定的結果,則該函數是確定的(deterministic)。如果函數的返回值 會因某些數據、變數、隨機數或任意不確定的值而受影響,則函數是不確定的。此外,如果存儲函數中使用了不確定的函數(如NOW()或CURRENT_TIMESTAMP()),則該存儲函數也是不確定的。

如果優化器知道函數是確定的,它會選擇一個更快更有效的執行計劃。你可以使用DETERMINISTIC關鍵字來定義這個routine。如果你想顯式將函數標記為不確定的(預設就是如此),可以使用NOT DETERMINISTIC關鍵字。

如果你將一個不確定的函數聲明為DETERMINISTIC,將返回一個錯誤結果。如果你將一個確定的函數聲明為NOT DETERMINISTIC,則某些情況下,該查詢語句的性能將大幅降低。

[NOT] DETERMINISTIC子句還會影響二進位日誌binary logging,因為日誌中的語句格式無法 存儲或替換不確定的語句。

CONTAINS SQL, NO SQL, READS SQL DATA 以及 MODIFIES SQL DATA是信息類的子句,它們告訴伺服器該函數是做什麼的。MariaDB不會對這些語句做任何語法檢查。如果不指定這些語句,則預設使用CONTAINS SQL。

>MODIFIES SQL DATA

MODIFIES SQL DATA意味著函數中包含了要修改資料庫中數據的語句。例如函數中使用了類似於DELETE, UPDATE, INSERT, REPLACE或DDL類的語句。

>READS SQL DATA

READS SQL DATA意味著函數中包含了從資料庫中讀取數據的語句,但是不會修改任何數據。例如函數中使用了不包含任何寫操作的SELECT語句。

>CONTAINS SQL

CONTAINS SQL意味著函數包含了至少一條SQL語句,但是它不會讀也不會寫資料庫。例如函數中包含了SET或DO子句。

>NO SQL

NO SQL意味著什麼?啥也不意味著。因為MariaDB目前除了SQL語言,不支持任何其他語言。

>Security

要想調用函數,你必須要擁有該函數的EXECUTE許可權。

MariaDB會自動為創建函數CREATE FUNCTION的用戶授予EXECUTE 和 ALTER ROUTINE許可權,即使使用了DEFINER子句。

每個函數都有一個關聯的賬號(即definer)。預設情況下,definer即為函數的創建者。可以使用DEFINER子句顯式指定關聯到其他賬號上。要使用DEFINER,你必須要擁有SUPER許可權。詳細信息見:Account Names

SQL SECURITY子句指定了當調用函數時所使用的許可權。如果SQL SECURITY的值為INVOKER,則將使用函數調用者的許可權去對比(即評估)函數體中的語句許可權。如果SQL SECURITY的值為DEFINER,則總是使用definer用戶的許可權去評估函數體的許可權。預設值為DEFINER。

通過該子句,你可以創建一個只允許某用戶訪問部分數據的函數。例如,你有一張存儲了員工信息的表,並且你已經授予了用戶roger對該表某些列(only on certain columns)的SELECT許可權。

CREATE TABLE employees (name TINYTEXT, dept TINYTEXT, salary INT);
GRANT SELECT (name, dept) ON employees TO roger;

可以定義一個函數來獲取部門中薪水最高的用戶,並授予EXECUTE許可權:

CREATE FUNCTION max_salary (dept TINYTEXT) RETURNS INT RETURN
  (SELECT MAX(salary) FROM employees WHERE employees.dept = dept);
GRANT EXECUTE ON FUNCTION max_salary TO roger;

由於SQL SECURITY的預設值為DEFINER,無論roger用戶何時調用該函數,都會使用你的許可權來執行其中的子查詢。只要你有查詢每個員工薪水的許可權,即使函數調用者不具備直接查詢薪水的許可權,他們也能獲取到每個部門的最高薪水。

>Character sets 和 collations

可以為函數聲明使用任意有效的字元集和排序規則character set and collation。如果定義了它們,COLLATE屬性需要定義在CHARACTER SET之後。

如果沒有指定字元集和排序規則,則使用函數創建時的系統預設值。即使之後系統預設字元集和排序規則改變了,函數所使用的字元集也不會隨之改變。這種情況下,應該重建函數並使用資料庫所使用的字元集和排序規則。

示例

下麵的函數示例使用了一個參數,併在函數中執行了一個SQL內置函數CONCAT(),最後返回結果。

CREATE FUNCTION hello (s CHAR(20))
    RETURNS CHAR(50) DETERMINISTIC
    RETURN CONCAT('Hello, ',s,'!');

SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world!  |
+----------------+

你可以在函數內部使用一個語句塊來操作數據(即使用DML),例如INSERT和UPDATE。下麵的例子中創建了一個函數計數器,它使用了一個臨時表來存儲當前的值。因為語句塊包含了語句終止符號";",因此必須首先使用DELIMITER語句改變語句的終止符,使得函數體中能夠使用分號。更多信息見Delimiters in the mysql client

CREATE TEMPORARY TABLE counter (c INT);
INSERT INTO counter VALUES (0);
DELIMITER //
CREATE FUNCTION counter () RETURNS INT
  BEGIN
    UPDATE counter SET c = c + 1;
    RETURN (SELECT c FROM counter LIMIT 1);
  END //
DELIMITER ;

字元集和排序規則:

CREATE FUNCTION hello2 (s CHAR(20))
  RETURNS CHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_bin' DETERMINISTIC
  RETURN CONCAT('Hello, ',s,'!');

 

回到Linux系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html
回到網站架構系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7576137.html
回到資料庫系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7586194.html
轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/8698943.html

註:若您覺得這篇文章還不錯請點擊右下角推薦,您的支持能激發作者更大的寫作熱情,非常感謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 使用Linux發行版時需要註意幾個方面的問題: 1. 包管理器 包管理器無疑時各家發行版的最大特色之一。軟體同時也是一個平臺是否能夠產生足夠的吸引力的來源之一。 manjaro使用CLI版的 ,同時附帶具有圖形前端的 ;同時manjaro基於archLinux,這意味著可以使用軟體眾多的archcn ...
  • 使用過 Ubuntu 的人都知道,Ubuntu 預設是不能以 root 登陸的,但是我們是不是就完全不能使用 root 進行登陸了呢?當然不是,只是我們需要做一些設置。而 Ubuntu 17.10 和之前的版本的設置方法都是不一樣的(包括 16.04 的方法在這裡也是行不通的),這裡分享一下 Ubu ...
  • 1.drbd多節點簡介 在drbd9以前,drbd一直只能配置兩個節點,要麼是primary/secondary,要麼是primary/primary。雖然在這些版本上也能配置第三個節點實現三路節點的同步,但這個第三節點一般都只當作備份drbd設備,幾乎沒人去使用drbd配置3節點。 但是在drbd ...
  • 公司的伺服器構架比較複雜,建立了一個主從熱備的centos7伺服器,分別有內網,外網,和VIP。 環境: ha-01 內網:192.168.1.221 外網:XX.XX.XX.221 ha-02 內網:192.168.1.222 外網:XX.XX.XX.222 VIP:192.168.1.232 公 ...
  • 1、左連接: var LeftJoin = from emp in ListOfEmployees join dept in ListOfDepartment on emp.DeptID equals dept.ID into JoinedEmpDept from dept in JoinedEmp ...
  • ViewFS Guide ViewFS Guide. 1 1 介紹... 1 2. The Old World(Prior to Federation). 1 2.1單個Namenode Clusters. 1 2.2 路徑使用... 1 2.3 路徑名的最佳實踐... 1 3 New World ...
  • 目標:自動同步Master 伺服器上面的Demo資料庫到Slave 伺服器的Demo資料庫中。 對於一些操作系統比較強而使用頻率又不高的東西,往往好久不去弄就忘記了,所以要經常記錄起來,方便日後查閱。 環境 資料庫版本:mysql5.7.17 Master 伺服器(Windows server201 ...
  • MyIASM,InnoDB主要區別: 1.MyIASM是非事物安全的,InnoDB是事物安全的。 事物安全的特點為更安全,遇到問題會自動恢復或從備份加事物日誌回覆,如果更新失敗,你的所有改變都變回原來。 非事物安全的優點為更快,所需的磁碟空間更小,執行更新時需要的記憶體更小,但是所有發生的改變都是永久 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...