200. 岛屿的个数
给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
# @author:leacoder
# @des: 染色法 + DFS 岛屿的个数
class Solution:
# 便于 上下左右扩散
dx = [-1, 1, 0, 0]
dy = [ 0, 0,-1, 1]
def numIslands(self, grid: List[List[str]]) -> int:
if not grid or not grid[0]: return 0 # 参数判断
self.max_x = len(grid);self.max_y = len(grid[0]);self.grid = grid
self.visited = set() # 不修改原数据
return sum([self.floodfill_DFS(i,j) for i in range(self.max_x) for j in range(self.max_y)])
# 深度优先 染色
def floodfill_DFS(self,x,y):
if not self._is_valid(x,y): # 判断节点是否合法
return 0
self.visited.add((x,y)) # 表示节点已经访问过
for k in range(4):
self.floodfill_DFS( x + self.dx[k], y + self.dy[k]) # 上下左右扩散
# @author:leacoder
# @des: 染色法 + BFS 岛屿的个数
class Solution:
# 便于 上下左右扩散
dx = [-1, 1, 0, 0]
dy = [ 0, 0,-1, 1]
def numIslands(self, grid: List[List[str]]) -> int:
if not grid or not grid[0]: return 0 # 参数判断
self.max_x = len(grid);self.max_y = len(grid[0]);self.grid = grid
self.visited = set() # 不修改原数据
return sum([self.floodfill_BFS(i,j) for i in range(self.max_x) for j in range(self.max_y)])
# 广度优先 染色
def floodfill_BFS(self,x,y):
if not self._is_valid(x,y): # 判断节点是否合法
return 0
self.visited.add((x,y)) # 标记节点已经访问过
queue = collections.deque() # 队列
queue.append((x,y))
while queue: # 不为空一直循环
cur_x, cur_y = queue.popleft() # 从队列左端取数据
for i in range(4):
new_x, new_y = cur_x + self.dx[i], cur_y + self.dy[i] #上下左右扩散
if self._is_valid(new_x, new_y): # 扩散后的数据是否合法
self.visited.add((new_x, new_y)) # 合法标记节点已经访问过
queue.append((new_x, new_y)) # 从右端加入队列
return 1
# 判断节点是否合法
def _is_valid(self,x,y):
# max_X max_y边界
if x < 0 or x >= self.max_x or y < 0 or y >= self.max_y:
return False
# 是 '0' 水 或者 已经访问过(处理过)
if self.grid[x][y] == '0' or ((x,y) in self.visited):
return False
return True
# @author:leacoder
# @des: 并查集 岛屿的个数
'''
1、初始化:将所有'1'(陆地)节点 root 指向自己
2、遍历:遍历所有节点,为1 相邻节点合并,为0 不管
3、遍历查询总共有多少root(可在2统计)
'''
class UnionFind(object):
def __init__(self,grid):
m, n = len(grid), len(grid[0])
self.count = 0
self.parent = [-1]*(m*n)
self.rank = [0]*(m*n)
for i in range(m):
for j in range(n):
if grid[i][j] == '1': # 为 1 时 count + 1
self.parent[i*n+j] = i*n+j # 初始化:将所有'1'(陆地)节点 root 指向自己
self.count +=1
def find(self,i):
if self.parent[i] != i:
self.parent[i] = self.find(self.parent[i]) # 如果parent不是自己,继续向上查找,找到属于哪个集合
return self.parent[i] # 如果parent是自己,返回这个值
def union(self,x,y):
rootx = self.find(x) # 找 x 的 parent
rooty = self.find(y) # 找 y 的 parent
if rootx != rooty: # 不同 不在一个集合中
''' 如果不管rank
if self.rank[rootx] > self.rank[rooty]:
self.parent[rooty] = rootx
elif self.rank[rootx] < self.rank[rooty]:
self.parent[rootx] = rooty
else:
self.parent[rooty] = rootx
self.rank[rootx] += 1
'''
self.parent[rootx] = rooty # 将两个 合为 同一个 集合中
self.count -=1 # 每次union count-1
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
if not grid or not grid[0]:
return 0
uf = UnionFind(grid)
directions = [(0,1),(0,-1),(-1,0),(1,0)]
m, n = len(grid), len(grid[0])
for i in range(m):
for j in range(n): # 遍历:遍历所有节点,为1 相邻节点合并,为0 不管
if grid[i][j] == '0':
continue
for d in directions: # 上下左右 扩散
nr,nc = i + d[0],j+d[1]
if nr >= 0 and nc >= 0 and nr < m and nc < n and grid[nr][nc] == '1': # 坐标合法 并且 为 1
uf.union(i*n+j,nr*n+nc) # 为1 相邻节点合并到同一集合
# 遍历查询总共有多少root(可在2统计)
return uf.count # 由于 union 中 被合并为同一集合 count -1 ,最后就剩 唯一的了
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
《MySQL必知必会》学习笔记 目录
讲授什么是游标以及如何使用游标
有时,需要在检索出来的行中前进或后退一行或多行。这就是使用游标的原因。
游标(cursor) 是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。
使用游标涉及几个明确的步骤
游标用DECLARE语句创建。DECLARE命名游标,并定义相应的SELECT语句,根据需要带WHERE和其他子句。
CREATE PROCEDURE processorders()
BEGIN
DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders;
END;*
注意使用 DELIMITER // 切换改变输入结束符为//,不然 ; 会被解析为结束符导致命令失败
DELIMITER //
CREATE PROCEDURE processorders()
BEGIN
DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders;
END//
DELIMITER ;
定义了名为ordernumbers的游标,使用了可以检索所有订单的SELECT语句
《MySQL必知必会》学习笔记 目录
如何利用SQL的INSERT语句将数据插入表中。
INSERT是用来插入(或添加)行到数据库表的。插入可以用几种方式使用:
把数据插入表中的最简单的方法是使用基本的INSERT语法,它要求指定表名和被插入到新行中的值。
INSERT INTO customers
VALUES ( NULL, 'Pep E. Lapew' , '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA', NULL, NULL);
没有输出 INSERT语句一般不会产生输出。
虽然这种语法很简单,但并不安全,应该尽量避免使用。上面的SQL语句高度依赖于表中列的定义次序,并且还依赖于其次序容易获得的信息。
编写INSERT语句的更安全(不过更烦琐)的方法如下:
INSERT INTO customers(cust_name, cust_address , cust_city , cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES ( 'Pep E. Lapew' , '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA', NULL, NULL);
此例子完成与前一个INSERT语句完全相同的工作,但在表名后的括号里明确地给出了列名。在插入行时, MySQL将用VALUES列表中的相应值填入列表中的对应项。 VALUES中的第一个值对应于第一个指定的列名。第二个值对应于第二个列名,如此等等。
下面的INSERT语句填充所有列(与前面的一样),但以一种不同的次序填充。因为给出了列名,所以插入结果仍然正确:
INSERT INTO customers(cust_name,cust_contact, cust_email ,cust_address , cust_city , cust_state, cust_zip, cust_country )
VALUES ( 'Pep E. Lapew' , NULL, NULL, '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA');
总是使用列的列表 一般不要使用没有明确给出列的列表的INSERT语句。使用列的列表能使SQL代码继续发挥作用,即使表结构发生了变化。
可以使用多条INSERT语句,甚至一次提交它们,每条语句用一个分号结束
INSERT INTO customers(cust_name, cust_address , cust_city , cust_state, cust_zip, cust_country)
VALUES ( 'Pep E. Lapew' , '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA');
INSERT INTO customers(cust_name, cust_address , cust_city , cust_state, cust_zip, cust_country)
VALUES ( 'M. Martian' , '42 Galaxy Way', 'New York', 'NY', '11213', 'USA');
或者,只要每条INSERT语句中的列名(和次序)相同,可以如下组合各语句:
INSERT INTO customers(cust_name, cust_address , cust_city , cust_state, cust_zip, cust_country)
VALUES ( 'Pep E. Lapew' , '100 Main Street', 'Los Angeles', 'CA', '90046', 'USA'),
( 'M. Martian' , '42 Galaxy Way', 'New York', 'NY', '11213', 'USA');
INSERT一般用来给表插入一个指定列值的行。但是, INSERT还存在另一种形式,可以利用它将一条SELECT语句的结果插入表中。这就是所谓的INSERT SELECT,顾名思义,它是由一条INSERT语句和一条SELECT语句组成的
INSERT INTO customers(cust_id ,cust_contact, cust_email ,cust_name ,cust_address , cust_city , cust_state, cust_zip, cust_country )
SELECT cust_id ,cust_contact, cust_email ,cust_name ,cust_address , cust_city , cust_state, cust_zip, cust_country FROM custnew;
这个例子使用INSERT SELECT从custnew中将所有数据导入customers。
这个例子导入了cust_id(假设你能够确保cust_id的值不重复)。也可以简单地省略这列(从INSERT和SELECT中),这样MySQL就会生成新值。
INSERT SELECT中SELECT语句可包含WHERE子句以过滤插入的数据。
如何利用UPDATE和DELETE语句进一步操纵表数据。
为了更新(修改)表中的数据,可使用UPDATE语句。可采用两种方式使用UPDATE:
不要省略WHERE子句 在使用UPDATE时一定要注意细心。因为稍不注意,就会更新表中所有行。
UPDATE语句由3部分组成,分别是:
客户10005现在有了电子邮件地址,因此他的记录需要更新,语句如下:
UPDATE customers SET cust_email = 'elmer@fudd.com' WHERE cust_id = 10005;
更新多个列的语法稍有不同:
UPDATE customers SET cust_name = 'The Fudds' , cust_email = 'elmer@fudd.com' WHERE cust_id = 10005;
为了删除某个列的值,可设置它为NULL(假如表定义允许NULL值)。
UPDATE customers SET cust_email = NULL WHERE cust_id = 10005;
为了从一个表中删除(去掉)数据,使用DELETE语句。可以两种方式使用DELETE
下面的语句从customers表中删除一行:
DELETE FROM customers WHERE cust_id = 10006;
在这个例子中,只删除客户10006。如果省略WHERE子句,它将删除表中每个客户。
DELETE不需要列名或通配符。 DELETE删除整行而不是删除列。为了删除指定的列,请使用UPDATE语句。
如果省略了WHERE子句,则UPDATE或DELETE将被应用到表中所有的行。换句话说,如果执行UPDATE而不带WHERE子句,则表中每个行都将用新值更新。类似地,如果执行DELETE语句而不带WHERE子句,表的所有数据都将被删除。
表的创建、更改和删除的基本知识。
为了用程序创建表,可使用SQL的CREATE TABLE语句。
为利用CREATE TABLE创建表,必须给出下列信息:
CREATE TABLE customers
(
cust_id int NOT NULL AUTO_INCREMENT,
cust_name char(50) NOT NULL,
cust_address char(50) NULL,
cust_city char(50) NULL,
cust_state char(50) NULL,
cust_zip char(50) NULL,
cust_country char(50) NULL,
cust_contact char(50) NULL,
cust_email char(255) NULL,
PRIMARY KEY (cust_id)
) ENGINE = InnoDB;
表的主键可以在创建表时用PRIMARY KEY关键字指定。
处理现有的表 在创建新表时,指定的表名必须不存在,否则将出错。如果要防止意外覆盖已有的表, SQL要求首先手工删除该表(请参阅后面的小节),然后再重建它,而不是简单地用创建表语句覆盖它。
允许NULL值的列也允许在插入行时不给出该列的值。不允许NULL值的列不接受该列没有值的行,换句话说,在插入或更新行时,该列必须有值。
每个表列或者是NULL列,或者是NOT NULL列,这种状态在创建时由表的定义规定。
CREATE TABLE orders
(
order_num int NOT NULL AUTO_INCREMENT,
order_date datetime NOT NULL ,
cust_id int NOT NULL,
PRIMARY KEY (order_num)
) ENGINE = InnoDB;
理解NULL 不要把NULL值与空串相混淆。 NULL值是没有值,它不是空串。如果指定’‘(两个单引号,其间没有字符),这在NOT NULL列中是允许的。空串是一个有效的值,它不是无值。 NULL值用关键字NULL而不是空串指定
主键值必须唯一。即,表中的每个行必须具有唯一的主键值。如果主键使用单个列,则它的值必须唯一。如果使用多个列,则这些列的组合值必须唯一。为创建由多个列组成的主键,应该以逗号分隔的列表给出各列名。
主键和NULL值 主键为其值唯一标识表中每个行的列。主键中只能使用不允许NULL值的列。允许NULL值的列不能作为唯一标识。
AUTO_INCREMENT告诉MySQL,本列每当增加一行时自动增量。每次执行一个INSERT操作时, MySQL自动对该列增量(从而才有这个关键字AUTO_INCREMENT),给该列赋予下一个可用的值。这样给每个行分配一个唯一的cust_id,从而可以用作主键值。
每个表只允许一个AUTO_INCREMENT列,而且它必须被索引
如果在插入行时没有给出值, MySQL允许指定此时使用的默认值。默认值用CREATE TABLE语句的列定义中的DEFAULT关键字指定。
CREATE TABLE orderitems
(
order_num int NOT NULL ,
order_item int NOT NULL ,
prod_id char(10) NOT NULL ,
quantity int NOT NULL DEFAULT 1,
item_price decimal(8,2) NOT NULL ,
PRIMARY KEY (order_num, order_item)
) ENGINE=InnoDB;
quantity列包含订单中每项物品的数量。在此例子中,给该列的描述添加文本DEFAULT 1指示MySQL,在未给出数量的情况下使用数量1。
MySQL与其他DBMS不一样,它具有多种引擎。它打包多个引擎,这些引擎都隐藏在MySQL服务器内,全都能执行CREATE TABLE和SELECT等命令。
以下是几个需要知道的引擎:
外键不能跨引擎 混用引擎类型有一个大缺陷。外键(用于强制实施引用完整性)不能跨引擎,即使用一个引擎的表不能引用具有使用不同引擎的表的外键。
为更新表定义,可使用ALTER TABLE语句。
为了使用ALTER TABLE更改表结构,必须给出下面的信息:
下面的例子给表添加一个列:
ALTER TABLE vendors ADD vend_phone CHAR(20);
删除刚刚添加的列,可以这样做:
ALTER TABLE vendors DROP COLUMN vend_phone;
ALTER TABLE的一种常见用途是定义外键。
删除表(删除整个表而不是其内容)非常简单,使用DROP TABLE语句即可:
DROP TABLE customers3;
使用RENAME TABLE语句可以重命名一个表:
RENAME TABLE customers2 TO customers3;
介绍视图究竟是什么,它们怎样工作,何时使用它们。我们还将看到如何利用视图简化前面章节中执行的某些SQL操作。
视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。
理解视图的最好方法是看一个例子。下面的SELECT语句从3个表中检索数据:
SELECT cust_name, cust_contact FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id AND orderitems.order_num = orders.order_num AND prod_id = 'TNT2';
此查询用来检索订购了某个特定产品的客户。任何需要这个数据的人都必须理解相关表的结构,并且知道如何创建查询和对表进行联结。为了检索其他产品(或多个产品)的相同数据,必须修改最后的WHERE子句。 现在,假如可以把整个查询包装成一个名为productcustomers的虚拟表,则可以如下轻松地检索出相同的数据: SELECT cust_name, cust_contact FROM productcustomers WHERE prod_id = ‘TNT2’; productcustomers是一个视图,作为视图,它不包含表中应该有的任何列或数据,它包含的是一个SQL查询(与上面用以正确联结表的相同的查询)。
重要的是知道视图仅仅是用来查看存储在别处的数据的一种设施。视图本身不包含数据,因此它们返回的数据是从其他表中检索出来的。
关于视图创建和使用的一些最常见的规则和限制。
视图的创建
视图的最常见的应用之一是隐藏复杂的SQL,这通常都会涉及联结。
CREATE VIEW productcustomers AS SELECT cust_name, cust_contact, prod_id
FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id AND orderitems.order_num = orders.order_num;
这条语句创建一个名为productcustomers的视图, 它联结三个表,以返回已订购了任意产品的所有客户的列表。 为检索订购了产品TNT2的客户,可如下进行
SELECT cust_name, cust_contact FROM productcustomers WHERE prod_id = 'TNT2';
视图的另一常见用途是重新格式化检索出的数据。
SELECT Concat( RTrim(vend_name), '(', RTrim(vend_country), ')' ) AS vend_title
FROM vendors ORDER BY vend_name;
假如经常需要这个格式的结果。不必在每次需要时执行联结,创建一个视图,每次需要时使用它即可。
CREATE VIEW vendorlocations AS SELECT Concat( RTrim(vend_name), '(', RTrim(vend_country), ')' ) AS vend_title
FROM vendors ORDER BY vend_name;
SELECT * FROM vendorlocations;
视 图 对 于 应 用 普 通 的 WHERE 子 句 也 很 有 用 。
CREATE VIEW customeremaillist AS SELECT cust_id, cust_name, cust_email
FROM customers WHERE cust_email IS NOT NULL;
这里的WHERE子句过滤了cust_email列中具有NULL值的那些行,使他们不被检索出来。
SELECT * FROM customeremaillist;
视图对于简化计算字段的使用特别有用。
SELECT prod_id, quantity, item_price, quantity*item_price AS expanded_price
FROM orderitems WHERE order_num = 20005;
将其转换为一个视图
CREATE VIEW orderitemsexpanded AS
SELECT order_num, prod_id, quantity, item_price, quantity*item_price AS expanded_price
FROM orderitems;
为检索订单20005的详细内容
SELECT * FROM orderitemsexpanded WHERE order_num = 20005;
迄今为止的所有视图都是和SELECT语句使用的。然而,视图的数据能否更新?答案视情况而定。 基本上可以说,如果MySQL不能正确地确定被更新的基数据,则不允许更新(包括插入和删除)。这实际上意味着,如果视图定义中有以下操作,则不能进行视图的更新:
介绍什么是存储过程,为什么要使用存储过程以及如何使用存储过程,并且介绍创建和使用存储过程的基本语法。
迄今为止,使用的大多数SQL语句都是针对一个或多个表的单条语句。并非所有操作都这么简单,经常会有一个完整的操作需要多条语句才能完成。
存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件,虽然它们的作用不仅限于批处理。
MySQL称存储过程的执行为调用,因此MySQL执行存储过程的语句为CALL。 CALL接受存储过程的名字以及需要传递给它的任意参数。
CALL productpricing ( @pricelow, @pricehigh, @priceaverage);
执行名为productpricing的存储过程,它计算并返回产品的最低、最高和平均价格。
一个例子——一个返回产品平均价格的存储过程
CREATE PROCEDURE productpricing()
BEGIN
SELECT Avg(prod_price) AS priceaverage FROM products;
END;
直接这样会报错 此存储过程名为productpricing,用CREATE PROCEDURE productpricing()语句定义。如果存储过程接受参数,它们将在()中列举出来。BEGIN和END语句用来限定存储过程体,过程体本身仅是一个简单的SELECT语句.
mysql命令行客户机的分隔符 默认的MySQL语句分隔符为;mysql命令行实用程序也使用;作为语句分隔符。如果命令行实用程序要解释存储过程自身内的;字符,则它们最终不会成为存储过程的成分,这会使存储过程中的SQL出现句法错误。 解决办法是临时更改命令行实用程序的语句分隔符,如下所示:
DELIMITER //
CREATE PROCEDURE productpricing()
BEGIN
SELECT Avg(prod_price) AS priceaverage FROM products;
END //
DELIMITER ;
其中, DELIMITER //告诉命令行实用程序使用//作为新的语句结束分隔符,可以看到标志存储过程结束的END定义为END//而不是END;。这样,存储过程体内的;仍然保持不动,并且正确地传递给数据库引擎。最后,为恢复为原来的语句分隔符,可使用DELIMITER ;
使用这个存储过程
CALL productpricing() ;
存储过程在创建之后,被保存在服务器上以供使用,直至被删除。
为删除刚创建的存储过程,可使用以下语句:
DROP PROCEDURE productpricing;
以下是productpricing的修改版本
CREATE PROCEDURE productpricing(
OUT pl DECIMAL(8,2),
OUT ph DECIMAL(8,2),
OUT pa DECIMAL(8,2)
)
BEGIN
SELECT Min(prod_price)
INTO pl
FROM products;
SELECT MAX(prod_price)
INTO ph
FROM products;
SELECT Avg(prod_price)
INTO pa
FROM products;
END;
同样可能需要DELIMITER 改变为如下
DELIMITER //
CREATE PROCEDURE productpricing(
OUT pl DECIMAL(8,2),
OUT ph DECIMAL(8,2),
OUT pa DECIMAL(8,2)
)
BEGIN
SELECT Min(prod_price)
INTO pl
FROM products;
SELECT MAX(prod_price)
INTO ph
FROM products;
SELECT Avg(prod_price)
INTO pa
FROM products;
END//
DELIMITER ;
CALL productpricing ( @pricelow, @pricehigh, @priceaverage);
这条CALL语句给出3个参数。它们是存储过程将保存结果的3个变量的名字。
变量名 所有MySQL变量都必须以@开始。
SELECT @priceaverage;
SELECT @pricelow, @pricehigh, @priceaverage;
CREATE PROCEDURE ordertotal(
IN onumber INT,
IN taxable BOOLEAN,
OUT ototal DECIMAL(8,2)
) COMMENT 'Obtain order total, optionally adding tax'
BEGIN
DECLARE total DECIMAL(8,2);
DECLARE taxrate INT DEFAULT 6;
SELECT Sum(item_price*quantity)
FROM orderitems WHERE order_num = onumber
INTO total;
IF taxable THEN
SELECT total+(total/100*taxrate) INTO total;
END IF;
SELECT total INTO ototal;
END;
注意使用 DELIMITER // 转
DELIMITER //
CREATE PROCEDURE ordertotal(
IN onumber INT,
IN taxable BOOLEAN,
OUT ototal DECIMAL(8,2)
) COMMENT 'Obtain order total, optionally adding tax'
BEGIN
DECLARE total DECIMAL(8,2);
DECLARE taxrate INT DEFAULT 6;
SELECT Sum(item_price*quantity)
FROM orderitems WHERE order_num = onumber
INTO total;
IF taxable THEN
SELECT total+(total/100*taxrate) INTO total;
END IF;
SELECT total INTO ototal;
END//
DELIMITER ;
注意 DELIMITER 与 ;之间的空格
添加了另外一个参数taxable,它是一个布尔值(如果要增加税则为真,否则为假)。在存储过程体中,用DECLARE语句定义了两个局部变量。 DECLARE要求指定变量名和数据类型,它也支持可选的默认值(这个例子中的taxrate的默认被设置为6%)。 SELECT语句已经改变,因此其结果存储到total(局部变量)而不是ototal。 IF语句检查taxable是否为真,如果为真,则用另一SELECT语句增加营业税到局部变量total。最后,用另一SELECT语句将total(它增加或许不增加营业税)保存到ototal。
COMMENT关键字 本例子中的存储过程在CREATE PROCEDURE语句中包含了一个COMMENT值。它不是必需的,但如果给出,将在SHOW PROCEDURE STATUS的结果中显示。
CALL ordertotal(20005, 0 , @total);
SELECT @total;
CALL ordertotal(20005, 1 , @total);
SELECT @total;
IF语句 这个例子给出了MySQL的IF语句的基本用法。 IF语句还支持ELSEIF和ELSE子句
为显示用来创建一个存储过程的CREATE语句,使用SHOW CREATEPROCEDURE语句:
SHOW CREATE PROCEDURE ordertotal;
为了获得包括何时、由谁创建等详细信息的存储过程列表, 使用SHOW PROCEDURE STATUS。
限制过程状态结果 SHOW PROCEDURE STATUS列出所有存储过程。为限制其输出,可使用LIKE指定一个过滤模式,例如:
SHOW PROCEDURE STATUS LIKE 'ordertotal';
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习