作者:mysql AB;翻译:陈朋奕
Why MySQL Statements are Legal in a Procedure Body
什么MySQL语句在存储过程体中是合法的?
什么样的SQL语句在Mysql存储过程中才是合法的呢?你可以创建一个包含INSERT, UPDATE,DELETE, SELECT, DROP, CREATE, REPLACE等的语句。你唯一需要记住的是如果代码中包含MySQL扩充功能,那么代码将不能移植。在标准SQL语句中:任何数据库定义语言都是合法的,如:
CREATE PROCEDURE p () DELETE FROM t; //
SET、COMMIT以及ROLLBACK也是合法的,如:
CREATE PROCEDURE p () SET @x = 5; //
MySQL的附加功能:任何数据操作语言的语句都将合法。
CREATE PROCEDURE p () DROP TABLE t; //
MySQL扩充功能:直接的SELECT也是合法的:
CREATE PROCEDURE p () SELECT 'a'; //
顺便提一下,我将存储过程中包括DDL语句的功能称为MySQL附加功能的原因是在SQL标准中把这个定义为非核心的,即可选组件。
在过程体中有一个约束,就是不能有对例程或表操作的数据库操作语句。例如下面的例子就是非法的:
CREATE PROCEDURE p1 ()
CREATE PROCEDURE p2 () DELETE FROM t; //
下面这些对MySQL 5.0来说全新的语句,过程体中是非法的:
CREATE PROCEDURE, ALTER PROCEDURE, DROP PROCEDURE, CREATE FUNCTION,
DROP FUNCTION, CREATE TRIGGER, DROP TRIGGER.
不过你可以使用
CREATE PROCEDURE db5.p1 () DROP DATABASE db5//
但是类似
"USE database"
语句也是非法的,因为MySQL假定默认数据库就是过程的工作场所。
Call the Procedure 调用存储过程
1.
现在我们就可以调用一个存储过程了,你所需要输入的全部就是CALL和你过程名以及一个括号再一次强调,括号是必须的当你调用例子里面的p1过程时,结果是屏幕返回了t表的内容
mysql> CALL p1() //
------
| s1 |
------
| 5 |
------
1 row in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
因为过程中的语句是
"SELECT * FROM t;"
2. Let me say that again, another way.
其他实现方式
mysql> CALL p1() //
和下面语句的执行效果一样:
mysql> SELECT * FROM t; //
所以,你调用p1过程就相当于你执行了下面语句:
"SELECT * FROM t;"
好了,主要的知识点"创建和调用过程方法"已经清楚了。我希望你能对自己说这相当简单。但是很快我们就有一系列的练习,每次都加一条子句,或者改变已经存在的子句。那样在写复杂部件前我们将会有很多可用的子句。
Characteristics Clauses 特征子句
1.
CREATE PROCEDURE p2 ()
LANGUAGE SQL NOT DETERMINISTIC SQL SECURITY DEFINER COMMENT 'A Procedure' SELECT CURRENT_DATE, RAND() FROM t //
这里我给出的是一些能反映存储过程特性的子句。子句内容在括号之后,主体之前。这些子句都是可选的,他们有什么作用呢?
2.
CREATE PROCEDURE p2 ()
LANGUAGE SQL NOT DETERMINISTIC
SQL SECURITY DEFINER
COMMENT 'A Procedure'
SELECT CURRENT_DATE, RAND() FROM t //
很好,这个LANGUAGE SQL子句是没有作用的。仅是为了说明下面过程的主体使用SQL语言编写。这条是系统默认的,但你在这里声明是有用的,因为某些DBMS(IBM的DB2)需要它,如果你关注DB2的兼容问题最好还是用上。此外,今后可能会出现除SQL外的其他语言支持的存储过程。
3.
CREATE PROCEDURE p2 ()
LANGUAGE SQL
NOT DETERMINISTIC SQL SECURITY DEFINER
COMMENT 'A Procedure'
SELECT CURRENT_DATE, RAND() FROM t //
下一个子句,NOT DETERMINISTIC,是传递给系统的信息。这里一个确定过程的定义就是那些每次输入一样输出也一样的程序。在这个案例中,既然主体中含有SELECT语句,那返回肯定是未知的因此我们称其NOT DETERMINISTIC。但是MySQL内置的优化程序不会注意这个,至少在现在不注意。
4.
CREATE PROCEDURE p2 ()
LANGUAGE SQL
NOT DETERMINISTIC
SQL SECURITY DEFINER COMMENT 'A Procedure'
SELECT CURRENT_DATE, RAND() FROM t //
下一个子句是SQL SECURITY,可以定义为SQL SECURITY DEFINER或SQL SECURITY INVOKER。
这就进入了权限控制的领域了,当然我们在后面将会有测试权限的例子。
SQL SECURITY DEFINER
意味着在调用时检查创建过程用户的权限(另一个选项是SQLSECURITY INVOKER)。
现在而言,使用
SQL SECURITY DEFINER
指令告诉MySQL服务器检查创建过程的用户就可以了,当过程已经被调用,就不检查执行调用过程的用户了。而另一个选项(INVOKER)则是告诉服务器在这一步仍然要检查调用者的权限。
5.
CREATE PROCEDURE p2 ()
LANGUAGE SQL
NOT DETERMINISTIC
SQL SECURITY DEFINER
COMMENT 'A Procedure' SELECT CURRENT_DATE, RAND() FROM t //
COMMENT 'A procedure'
是一个可选的注释说明。
最后,注释子句会跟过程定义存储在一起。这个没有固定的标准,我在文中会指出没有固定标准的语句,不过幸运的是这些在我们标准的SQL中很少。
6.
CREATE PROCEDURE p2 ()
LANGUAGE SQL
NOT DETERMINISTIC
SQL SECURITY DEFINER
COMMENT ''
SELECT CURRENT_DATE, RAND() FROM t //
上面过程跟下面语句是等效的:
CREATE PROCEDURE p2 ()
SELECT CURRENT_DATE, RAND() FROM t //
特征子句也有默认值,如果省略了就相当于:
LANGUAGE SQL NOT DETERMINISTIC SQL SECURITY DEFINER COMMENT ''
Digressions一些题外话
Digression:
调用p2()//的结果
mysql> call p2() //
-------------- -----------------
| CURRENT_DATE | RAND() |
-------------- -----------------
| 2004-11-09 | 0.7822275075896 |
-------------- -----------------
1 row in set (0.26 sec)
Query OK, 0 rows affected (0.26 sec)
当调用过程p2时,一个SELECT语句被执行返回我们期望获得的随机数。
Digression: sql_mode unchanging
不会改变的
sql_mode
mysql> set sql_mode='ansi' //
mysql> create procedure p3()select'a'||'b'//
mysql> set sql_mode=''//
mysql> call p3()//
------------
| 'a' || 'b' |
------------
| ab |
------------
MySQL在过程创建时会自动保持运行环境。例如:我们需要使用两条竖线来连接字符串但是这只有在sql mode为ansi的时候才合法。如果我们将sql mode改为non-ansi,不用担心,它仍然能工作,只要它第一次使用时能正常工作。
Exercise 练习
Question
问题
如果你不介意练习一下的话,试能否不看后面的答案就能处理这些请求。
创建一个过程,显示`Hello world`。用大约5秒时间去思考这个问题,既然你已经学到了这里,这个应该很简单。当你思考问题的时候,我们再随机选择一些刚才讲过的东西复习:
DETERMINISTIC
(确定性)子句是反映输出和输入依赖特性的子句…调用过程使用CALL过程名(参数列表)方式。好了,我猜时间也到了。
Answer
答案
好的,答案就是在过程体中包含
"SELECT 'Hello, world'"
语句
MySQL
mysql> CREATE PROCEDURE p4 () SELECT 'Hello, world' //
Query OK, 0 rows affected (0.00 sec)
mysql> CALL p4()//
--------------
| Hello, world |
--------------
| Hello, world |
--------------
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Parameters 参数
让我们更进一步的研究怎么在存储过程中定义参数
1. CREATE PROCEDURE p5
() ...
2. CREATE PROCEDURE p5
([IN] name data-type) ...
3. CREATE PROCEDURE p5
(OUT name data-type) ...
4. CREATE PROCEDURE p5
(INOUT name data-type) ...
回忆一下前面讲过的参数列表必须在存储过程名后的括号中。上面的第一个例子中的参数列表是空的,第二个例子中有一个输入参数。这里的词IN可选,因为默认参数为IN(input)。
第三个例子中有一个输出参数,第四个例子中有一个参数,既能作为输入也可以作为输出。
IN example 输入的例子
mysql> CREATE PROCEDURE p5(p INT) SET @x = p //
Query OK, 0 rows affected (0.00 sec)
mysql> CALL p5(12345)//
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @x//
-------
| @x |
-------
| 12345 |
-------
1 row in set (0.00 sec)
这个IN的例子演示的是有输入参数的过程。在过程体中我将会话变量x设定为参数p的值。然后调用过程,将12345传入参数p。选择显示会话变量@x,证明我们已经将参数值12345传入。
OUT example 输出的例子
mysql> CREATE PROCEDURE p6 (OUT p INT)
-> SET p = -5 //
mysql> CALL p6(@y)//
mysql> SELECT @y//
------
| @y |
------
| -5 |
------
这是另一个例子。这次的p是输出参数,然后在过程调用中将p的值传入会话变量@y中。
在过程体中,我们给参数赋值-5,在调用后我们可以看出,OUT是告诉DBMS值是从过程中传出的。
同样我们可以用语句
"SET @y = -5;"
来达到同样的效果
Compound Statements 复合语句
现在我们展开的详细分析一下过程体:
CREATE PROCEDURE p7 ()
BEGIN
SET @a = 5;
SET @b = 5;
INSERT INTO t VALUES (@a);
SELECT s1 * @a FROM t WHERE s1 >= @b;
END; // /* I won't CALL this.
这个语句将不会被调用
*/
完成过程体的构造就是BEGIN/END块。这个BEGIN/END语句块和Pascal语言中的BEGIN/END是基本相同的,和C语言的框架是很相似的。我们可以使用块去封装多条语句。在这个例子中,我们使用了多条设定会话变量的语句,然后完成了一些insert和select语句。如果你的过程体中有多条语句,那么你就需要BEGIN/END块了。BEGIN/END块也被称为复合语句,在这里你可以进行变量定义和流程控制。
未完待续...

Vue3+TS+Vite开发技巧:如何进行数据加密和存储随着互联网技术的快速发展,数据的安全性和隐私保护变得越来越重要。在Vue3+TS+Vite开发环境下,如何进行数据加密和存储,是每个开发人员都需要面对的问题。本文将介绍一些常用的数据加密和存储的技巧,帮助开发人员提升应用的安全性和用户体验。一、数据加密前端数据加密前端加密是保护数据安全性的重要一环。常用

什么是缓存?缓存(发音为ka·shay)是一种专门的高速硬件或软件组件,用于存储经常请求的数据和指令,这些数据和指令又可用于更快地加载网站、应用程序、服务和系统的其他部分。缓存使最常访问的数据随时可用。缓存文件与缓存内存不同。缓存文件是指经常需要的文件,如PNG、图标、徽标、着色器等,多个程序可能需要这些文件。这些文件存储在您的物理驱动器空间中,通常是隐藏的。另一方面,高速缓存内存是一种比主内存和/或RAM更快的内存类型。它极大地减少了数据访问时间,因为与RAM相比,它更靠近CPU并且速度

PHP和swoole如何实现高效的数据缓存和存储?概述:在Web应用开发中,数据的缓存和存储是非常重要的一部分。而PHP和swoole提供了一种高效的方法来实现数据的缓存与存储。本文将介绍如何使用PHP和swoole来实现高效的数据缓存和存储,并给出相应的代码示例。一、swoole简介:swoole是一个针对PHP语言开发的,高性能的异步网络通信引擎,它可以

本文转载自微信公众号「活在信息时代」,作者活在信息时代。转载本文请联系活在信息时代公众号。对于熟悉数据库操作的同学来说,编写优美的SQL语句,从数据库中想方设法找出自己需要的数据,是常规操作了。而对于熟悉机器学习的同学来说,获取数据,对数据进行预处理,建立模型,确定训练集和测试集,用训练好的模型对未来进行一系列的预测,也是一种常规操作了。那么,我们能否将两种技术结合起来呢?我们看到数据库里存储了数据,而进行预测需要基于以往的数据。如果我们通过数据库里现有的数据,对于未来的数据进行查询的话,那么是

使用PHP数组实现数据缓存和存储的方法和技巧随着互联网的发展和数据量的急剧增长,数据缓存和存储成为了我们在开发过程中必须要考虑的问题之一。PHP作为一门广泛应用的编程语言,也提供了丰富的方法和技巧来实现数据缓存和存储。其中,使用PHP数组进行数据缓存和存储是一种简单而高效的方法。一、数据缓存数据缓存的目的是为了减少对数据库或其他外部数据源的访问次数,从而提高

重返未来1999中玩家会在其中面对很多的关卡挑战,而且其中一个个不同的关卡所带来的挑战都完全不一样,而6-24作为其中一个关卡,也肯定会有着不少玩家想知道这一关卡该如何去进行挑战吧,所以下面也是会带来相关的通关方法了。重返未来19996-24通关方法1、一句话挂30层燃烧后,等boss眩晕一顿胖揍。2、一回合优先用主C和142d挂燃烧。3、二回合用辅助和奶妈小技能挂燃烧+和主c卡攒个大招。4、三回合boss就眩晕了,然后直接用大招和伤害技能胖揍。

9月19日,中国国际工业博览会的第二十三届正式开幕。本届工博会的主题是“碳循新工业、数聚新经济”,规模庞大,能级高,展品丰富,共有2800多家国内外展商参展。其中,威刚工控作为工业嵌入式存储领导品牌,围绕人工智能应用需求,重点展示了高性能存储解决方案,并展示了网络安全人工智能边缘计算设备、人工智能视觉控制器以及人工智能大数据分析设备的客户样机成功案例。通过展示有效解决人工智能场景中的难题和痛点的解决方案,为人工智能时代提供了新一代高性能存储技术的支持威刚展台的C位区域全面展示了各种主流规格的存储

鸣潮异想奇境难度3怎么过通关方式分享。鸣潮里面很多人都在通关这个异想奇境难度3了呢,这一关其实还是有点难度的,很多小伙伴们还不知道该怎么办比较好,不过不用担心,小编为大家带来了其中的攻略,你也来试试看吧。鸣潮异想奇境难度3怎么过鸣钟之龟角色强化共鸣技能可以提升我们气动的效果了,这样一来打出的攻击效率也会提升到,伤害也会更加的大的,不过大家要是有效果替换也是可以换取的。〔隐喻〕前三关选择:林中骄阳:可以让忌炎的伤害提升很多,技能的使用次数变多的话那么可以打出非常不错的暴击效果了。防护装置:用共鸣技


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

Dreamweaver Mac版
ビジュアル Web 開発ツール
