首頁 資料庫 mysql教程 存储程序(1)——MYSQL_MySQL

存储程序(1)——MYSQL_MySQL

May 27, 2016 pm 02:12 PM
程式

bitsCN.com

MySQL支持把几种对象存放在服务器端供以后使用。这几种对象有一些可以根据情况通过程序代码调用,有一些会在数据表被修改时自动执行,还有一些可以在预定时刻自动执行。它们包括以下几种:

1.存储函数(stored function)。返回一个计算结果,该结果可以用在表达式里。
2.存储过程(stored procedure)。不直接返回一个结果,但可以用来完成一般的运算或是生成一个结果集并传递回客户。
3.触发器(trigger)。与数据表相关联,当那个数据表被工NSERT、DELETE或UPDATE语句修改时,触发器将自动执行。
4.事件(event)。根据时间表在预定时刻自动执行。

MySQL对存储函数和存储过程的支持始于5.0.0版本,对触发器和事件的支持分别始于5.0.2版本和5.1.6版本。存储程序有以下优点和能力:

1.存储程序对象的可执行部分可以用复合语句来编写,复合语句对SQL语法进行了扩展,可以包括代码块、循环和条件语句。
2.存储程序都被保存在服务器端,定义它们所需要的代码只需在它们被创建时通过网络传递一次,而不是每次执行都要传递一次。这大大减少了开销。
3.它们可以把复杂的计算封装为程序单元,而你可以简单地通过程序单元的名字来调用它们。你甚至可以把一组存储程序打包为一个“函数库”供其他应用程序调用。
4.它们提供了一种错误处理机制。
5.它们可以提高数据库的安全性。你可以通过选择存储程序执行时所需的权限下来对敏感数据的访问情况进行限制和调控。

存储程序。泛指各种类型的存储对象(存储函数、存储过程、触发器、事件)。存储例程(stored routine ),特指存储函数和存储过程。这两种对象的定义语法很相似,所以很自然地把它们放在一起讨论。在开始讨论各种类型的存储程序之前,我们首先学习一下:复合语句。

1.复合语句和语句分隔符

简单的存储程序只包含一条SQL语句,在编写时不需要特殊对待。下面的存储过程使用了一条SELECT语句来列出sampdb数据库里的数据表的名字:

PROCEDURE sampdb_tables()SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLESWHERE TABLE_SCHEMA=’sampdb’ ORDER BY TABLE_NAME;
登入後複製

不过,存储程序并非只能包含一条简单的SQL语句。它们可以包含多条SQL语句,可以使用局部变量、条件语句、循环和嵌套语句块等多种语法构造。要使用这些构造编写存储程序,就需要用到复合语句。复合语句由BEGIN开头,END结束,在它们之间可以写出任意数量的语句,这些语句构成了一个语句块。下面的存储过程将显示一条欢迎消息,其中有你的用户名;如果你是一位匿名用户,用户名将是“earthing":

CREATE PROCEDURE greetings()BEGIN    #77=16  for username+60 for hostname+1 for '@'    DECLARE user CHAR(77) CHARACTER SET utf8;    SET user = (SELECT CURRENT USER());    IF INSTR(user,’@’)>0 THEN    #返回字符串在某一个字段的内容中的位置, 没有找到字符串返回0,否则返回位置(从1开始)        SET user=SUBSTRING_INDEX(user, '@', 1);    END IF;    IF user = '' THEN        SET user='earthling';    END IF;    SELECT CONCAT('Greetings,',user, '!') AS greeting;END;
登入後複製

在使用复合语句时,必须考虑和解决这样一个问题:复合语句块里的语句必须以分号(;)彼此隔开,但因为分号同时也是mysql程序默认使用的语句分隔符,所以在使用mysql程序定义存储程序时会发生冲突。
解决这个问题的办法是使用delimiter命令把mysql程序的语句分隔符重定义为另一个字符或字符串,它必须是在存储例程的定义里没有出现过的。这样一来,mysql程序就不会把分号解释为语句终止符了,它将把整个对象定义作为一条语句传递给服务器。在定义完存储程序之后,可以把mysql程序的语句终止符重新定义为分号。

use weibo;delimiter $CREATE PROCEDURE show_times()BEGIN    SELECT 'Local time is:', CURRENT_TIMESTAMP;    SELECT 'UTC time is:', UTC_TIMESTAMP;END$delimiter ;-- delimiter后空格加分号,将分号设置为分隔符CALL show_times();
登入後複製

定义一个存储过程时把mysql程序的默认分隔符临时改变为$,然后在恢复了mysql程序的默认分隔符之后执行了那个存储过程:

Local time is:2014-01-15 23:00:26 
image

分隔符不必非得是$字符,也不必非得是单个的字符:

delimiter EOF
登入後複製

这里的原则是:只要在某个存储程序内部的语句里会用到分号,就应该在定义这个存储程序时临时改变mysql程序的分隔符。

2.存储函数和存储过程

存储函数将向调用者返回一个计算结果,这个结果可以用在表达式里(就像COS()或HEX()这样的内建函数那样)。存储过程需要使用CALL语句来调用,是一个独立的操作,不能用在表达式里。使用存储过程的情况主要有两种:(1)只需通过运算来实现某种效果或动作而无需返回一个值,(2)运算会返回多个结果集(函数做不到这一点)。这只是些指导性建议,不是硬性规定。
比如说,如果你需要返回两个或更多的值,就不能使用函数。但你可以使用一个过程,因为过程支持的参数类型允许它们的值在过程执行期间被设置,而调用者可以在过程返回后去访问那些值。

存储函数要用CREATE FUNCTION语句来创建,存储过程要用CREATE PROCEDURE语句来创建。下面的例子将创建一个函数,该函数有一个代表着年份的整数参数。(为了与数据表或数据列的名字有所区别,参数命名时将使用p_前缀)。

delimiter $CREATE FUNCTION count_born_in_year(p_year INT)RETURNS INTREADS SQL DATABEGIN    RETURN (SELECT COUNT(*) FROM president WHERE YEAR(birtb) = p_year);END$delimiter ;
登入後複製

这个函数有一条用来表明其返回值数据类型的RETURNS子句和一个用来计算那个值的函数体。函数体至少需要包含一条RETURN语句,用来向调用者返回一个值。把计算定义为函数的好处是可以方便地执行它而无须每次都写出所有的逻辑,你可以像使用内建函数那样来调用存储函数:

SELECT count_born_in_year(1990);
登入後複製

你无法让一个给定的函数返回多个值。你可以编写任意多个函数,然后在同一条语句里调用它们全体。另一个办法是使用一个存储过程并通过它的OUT参数“返回”多个值。存储过程负责计算那些值并把它们赋值给相应的参数,而那些参数可以在过程返回后由调用者访问。如果你定义了一个与某个MySQL内建函数同名的存储函数,在调用它时就必须用数据库的名字对该函数的名字进行限定以避免歧义。

存储过程和存储函数很相似,但它不返回值。因此,它没有RETURNS子句或任何RETURN语句。下面这个简单的存储过程和count_born_in_year()函数很相似,它将显示一个结果集而不是把计算结果作为其返回值。

delimiter $CREATE PROCEDURE show_born_in_year(p_year INT)BEGIN    SELECT first_name, last_name, birth, death    FROM president    WHERE YEAR(birth)=P_year;END$delimiter ;
登入後複製

与存储函数不同,存储过程不能用在表达式里,它们只能通过CALL语句来调用。如下所示:

CALL show_born_in_year(1990);
登入後複製

前面的例子都是选取信息,但存储例程还可以用来修改数据表,如下例所示:

delimiter $CREATE PROCEDURE update_expiration (p_id INT UNSIGNED, p_date DATE)BEGIN    UPDATE member SET expiration=p_date WHERE member_id=p_id;END$delimiter ;
登入後複製

存储函数必须遵守这样一条限制:不允许对调用本函数的语句正在读或写的数据表进行修改。存储过程通常没有这个限制,但如果它们是从存储函数里被调用,就需要遵守这条限制。

3.存储函数和存储过程的权限

存储函数和存储过程属于数据库。要想创建存储函数或存储过程,必须拥有那个数据库的CREATE ROUTINE权限。在默认的情况下,当你创建一个存储例程时,服务器将自动地把EXECUTE和ALTER ROUTINE权限授予你(如果你还没有获得这些权限),这样你才可以执行那个例程或删除它。当你删除那个例程时,服务器将自动撤销那些权限。如果你不想使用这种自动化的权限授予/撤销机制,把automatic_sp_privileges系统变量设置为0即可。

如果服务器启用了二进制日志功能,存储函数还需要遵守一些额外的限制条件(不允许创建不确定或是会修改数据的存储函数)以保证二进制日志能够安全地完成备份和复制操作。这些限制条件如下:
1.如果log_bin_trust_function_creators系统变量没有被激活,你就必须具备SUPER权限才能创建存储函数。在此前提下,你创建的每一个函数都必须是确定的,并且不得修改数据。为了表明这一点,需要使用DETERMINISTIC、NO SQL或READS SQL DATA之一来定义存储函数。
2.如果log bin_trust_function_creators系统变量已被激活,则没有任何限制。只有当你可以相信MySQL服务器上的所有用户都不会去定义不安全的存储函数时,这种设置才是最适当的。

与log_bin_trust_function_creators系统变量有关的限制条件同样适用于触发器的创建工作。

4.存储过程的参数类型

存储过程的参数分为3种类型。对于IN参数,调用者把一个值传递给过程,过程可以对这个值进行修改,但任何修改在过程返回后对调用者是不可见的。OUT参数刚好相反,过程把一个值赋值给OUT参数,这个值在过程返回后可以由调用者访问。INOUT参数允许调用者向过程传递一个值,然后再取回一个值。
要想明确地为参数指定类型,在参数表里把IN, OUT或INOUT写在参数名字前面即可。如果没有为参数指定类型,其默认类型将是IN。

在使用OUT或INOUT参数时,在调用过程时需要给出一个变量名。过程可以设置参数的值,相应的变量将在过程返回时获得那个值。如果想让某个存储过程返回多个结果值,OUT和INOUT参数类型将非常有用(存储函数只能返回一个值,不能胜任)。下面的过程演示了OUT参数的用法。它将分别统计出student数据表里的男生和女生人数并通过它的参数返回这两个计数值,让调用者可以访问它们:

delimiter $CREATE PROCEDURE count_students_by_sex(OUT p_male INT, OUT p_female INT)BEGIN    SELECT COUNT(*) FROM student WHERE sex= 'F' INTO p_female;    SELECT COUNT(*) FROM student WHERE sex= 'F' INTO p_female;END$delimiter ;
登入後複製

在调用这个过程时,请把各个参数替换为相应的用户定义变量。这个过程将把计数值放到这些参数里,在它返回之后,那些变量将包含计数值:

CALL count_students_by_sex(@mcoant, @fcount);SELECT 'Number of male students:',@mcount;
登入後複製

IN、OUT和INOUT关键字不适用于存储函数、触发器或事件。对于存储函数,所有的参数都像IN参数。触发器和事件则根本没有任何参数。下一部分介绍:触发器和事件。

bitsCN.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1421
52
Laravel 教程
1315
25
PHP教程
1266
29
C# 教程
1239
24
如何在iPhone中使Google地圖成為預設地圖 如何在iPhone中使Google地圖成為預設地圖 Apr 17, 2024 pm 07:34 PM

iPhone上的預設地圖是Apple專有的地理位置供應商「地圖」。儘管地圖越來越好,但它在美國以外的地區運作不佳。與谷歌地圖相比,它沒有什麼可提供的。在本文中,我們討論了使用Google地圖成為iPhone上的預設地圖的可行性步驟。如何在iPhone中使Google地圖成為預設地圖將Google地圖設定為手機上的預設地圖應用程式比您想像的要容易。請依照以下步驟操作–先決條件步驟–您必須在手機上安裝Gmail。步驟1–開啟AppStore。步驟2–搜尋“Gmail”。步驟3–點選Gmail應用程式旁

修正: 操作員拒絕 Windows 工作排程程式中的要求錯誤 修正: 操作員拒絕 Windows 工作排程程式中的要求錯誤 Aug 01, 2023 pm 08:43 PM

要自動化任務和管理多個系統,任務規劃軟體是您武器庫中的寶貴工具,尤其是對於系統管理員而言。 Windows任務規劃程式完美地完成了這項工作,但最近許多人報告說操作員拒絕了請求錯誤。這個問題存在於作業系統的所有迭代中,即使已經廣泛報告和涵蓋,也沒有有效的解決方案。繼續閱讀以找到真正對其他人有用的內容!操作員或管理員拒絕了任務計畫程式0x800710e0中的請求是什麼?任務計劃程式允許在沒有使用者輸入的情況下自動執行各種任務和應用程式。您可以使用它來安排和組織特定應用程式、配置自動通知、幫助傳遞訊息等。它

如何在Windows 10和11上按臉部對照片進行排序 如何在Windows 10和11上按臉部對照片進行排序 Aug 08, 2023 pm 10:41 PM

Windows的操作隨著每個版本而變得越來越好,具有誘人的功能來改善使用者體驗。使用者希望在Windows10和11上探索的一項功能是能夠按臉部對照片進行排序。此功能可讓您透過臉部辨識對朋友和家人的照片進行分組。聽起來很有趣,對吧?繼續閱讀如何了解如何利用該功能。我可以在Windows上按臉對照片進行分組嗎?是的,您可以使用「照片」應用程式在Windows10和11上按人臉將圖片分組。但是,此功能在照片應用程式版本上不可用。此外,您可以使用「人脈」標籤將這些照片連結到聯絡人。因此,使用此功能可以

如何透過C++編寫一個簡單的倒數計時程式? 如何透過C++編寫一個簡單的倒數計時程式? Nov 03, 2023 pm 01:39 PM

C++是一種廣泛使用的程式語言,在編寫倒數計時器方面非常方便且實用。倒數計時程式是一種常見的應用,它能為我們提供非常精確的時間計算和倒數功能。本文將介紹如何使用C++來寫一個簡單的倒數計時程式。實現倒數程序的關鍵就是使用計時器來計算時間的流逝。在C++中,我們可以使用time.h頭檔中的函數來實作計時器的功能。下面是一個簡單的倒數計時程式的程式碼

iPhone中缺少時鐘應用程式:如何修復 iPhone中缺少時鐘應用程式:如何修復 May 03, 2024 pm 09:19 PM

您的手機中缺少時鐘應用程式嗎?日期和時間仍將顯示在iPhone的狀態列上。但是,如果沒有時鐘應用程序,您將無法使用世界時鐘、碼錶、鬧鐘等多項功能。因此,修復時鐘應用程式的缺失應該是您的待辦事項清單的首位。這些解決方案可以幫助您解決此問題。修復1–放置時鐘應用程式如果您錯誤地從主畫面中刪除了時鐘應用程序,您可以將時鐘應用程式放回原位。步驟1–解鎖iPhone並開始向左側滑動,直到到達「應用程式庫」頁面。步驟2–接下來,在搜尋框中搜尋「時鐘」。步驟3–當您在搜尋結果中看到下方的「時鐘」時,請按住它並

如何使用任務規劃程式開啟網站 如何使用任務規劃程式開啟網站 Oct 02, 2023 pm 11:13 PM

您是否每天在大約相同的時間頻繁地造訪同一網站?這可能會導致花費大量時間打開多個瀏覽器選項卡,並在執行日常任務時使瀏覽器充滿混亂。好吧,打開它而不必手動啟動瀏覽器怎麼樣?這非常簡單,不需要您下載任何第三方應用程序,如下所示。如何設定任務計劃程序以開啟網站?按鍵,在搜尋框中鍵入任務計劃程序,然後按一下開啟。 Windows在右側側邊欄上,按一下「建立基本任務」選項。在名稱欄位中,輸入要開啟的網站的名稱,然後按一下下一步。接下來,在觸發器下,按一下時間頻率並點擊下一步。選擇您希望活動重複多長時間並點擊下一步。選擇啟

iOS 17:如何在「訊息」中組織iMessage應用程式 iOS 17:如何在「訊息」中組織iMessage應用程式 Sep 18, 2023 pm 05:25 PM

在iOS17中,蘋果不僅增加了幾個新的訊息功能,而且還調整了訊息應用程式的設計,使其外觀更乾淨。現在,所有iMessage應用程式和工具(如相機和照片選項)都可以透過點擊鍵盤上方和文字輸入欄位左側的「+」按鈕來存取。點擊“+”按鈕會彈出一個選單列,該列具有預設的選項順序。從頂部開始,有相機,照片,貼紙,現金(如果可用),音訊和位置。最底部是一個「更多」按鈕,點擊該按鈕時會顯示任何其他已安裝的訊息應用程式(您也可以向上滑動以顯示此隱藏清單)。如何重新組織您的iMessage應用程式您可以透過以下方

無法允許存取 iPhone 中的相機和麥克風 無法允許存取 iPhone 中的相機和麥克風 Apr 23, 2024 am 11:13 AM

您在嘗試使用應用程式時是否收到“無法允許存取攝影機和麥克風”?通常,您可以在需要提供的基礎上向特定物件授予攝影機和麥克風權限。但是,如果您拒絕權限,攝影機和麥克風將無法運作,而是顯示此錯誤訊息。解決這個問題是非常基本的,你可以在一兩分鐘內完成。修復1–提供相機、麥克風權限您可以直接在設定中提供必要的攝影機和麥克風權限。步驟1–轉到“設定”選項卡。步驟2–打開「隱私與安全」面板。步驟3–在那裡打開“相機”權限。步驟4–在裡面,您將找到已要求手機相機權限的應用程式清單。步驟5–開啟指定應用的“相機”

See all articles