MySQL存储过程之函数及元数据

1.创建函数

 1 CREATE FUNCTION factorial (n DECIMAL(3,0))      
 2     RETURNS DECIMAL(20,0)
 3     DETERMINISTIC
 4 BEGIN  
 5     DECLARE factorial DECIMAL(20,0DEFAULT 1;
 6     DECLARE counter DECIMAL(3,0);
 7     SET counter = n;  
 8     factorial_loop: REPEAT
 9         SET factorial = factorial * counter;
10         SET counter = counter - 1;
11         UNTIL counter = 1
12     END REPEAT;
13     RETURN factorial;
14 END // 

  函数跟过程很相似,唯一需要指出的语法上的不同:创建函数后必须有RETURN语句指定返回值类型并返回相应类型的值.下面是函数使用的例子:

1 INSERT INTO t VALUES (factorial(pi)) //  
2 SELECT s1, factorial (s1) FROM t //  
3 UPDATE t SET s1 = factorial(s1)  WHERE factorial(s1) < 5 //

  注意在函数中访问表,这使得函数不如存储过程强大,以下是不能出现在函数中的限制:

ALTER 'CACHE INDEX' CALL COMMIT CREATE DELETE 
DROP 'FLUSH PRIVILEGES' GRANT INSERT KILL 
LOCK OPTIMIZE REPAIR REPLACE REVOKE 
ROLLBACK SAVEPOINT 'SELECT FROM table' 
'SET system variable' 'SET TRANSACTION' 
SHOW 'START TRANSACTION' TRUNCATE UPDATE

  以下指令是可以出现在函数中的:

'BEGIN END'
DECLARE
IF
ITERATE
LOOP
REPEAT
RETURN
'SET declared variable'
WHILE 

2. Metadata元数据

  我们创建的过程或函数,都会保存在MySQL数据库中.如果要查看MySQL实际上保存了什么信息,有以下四种方法,分别是两个SHOW和两个SELECT语句:

  1) Show: mysql> show create procedure p6//  

+-------------+------------+--------------------------------------------------------------------+  

 | Procedure | sql_mode |            Create Procedure                                              | 

+-------------+------------+--------------------------------------------------------------------+  

 |      p6      |                | CREATE PROCEDURE `db5`.`p6`(out p | int) set p = -5 |

+-------------+------------+--------------------------------------------------------------------+  

  这同SHOW CREATE TABLE及其他类似MySQL语句一样.它并不返回你创建过程时设定的返回值,但大部分情况下已经够用了.

  2) Show: mysql> SHOW PROCEDURE STATUS LIKE 'p6'//  第二种获得无数据信息的方法是执行SHOW PROCEDURE STATUS,这种方法可以返回更多信息的细节.

  3) SELECT from mysql.proc: SELECT * FROM mysql.proc WHERE name = 'p6'//  这种方法提供的信息是最多的.

  4) SELECT from information_schema:

1 mysql    > SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM  INFORMATION_SCHEMA.COLUMNS       
2         -> WHERE TABLE_NAME = 'ROUTINES';// 

  这是被推荐的方式,因为其他方式可能会出现错误:

  1) 其他DBMS如SQL Server 2000,使用information_schema,只有MySQL才有SHOW方式.

  2) 我们访问mysql.proc的权限是没有保证的,但有访问information_schema视图的权限,每个用户都有隐式的对当局者迷information_schema数据库的SELECT权限.

  3) SELECT功能很多,可以计算表达式,分组,排序,产生可以获取信息的结果集.而这些功能SHOW没有.

  下面是使用该方法的例子,首先使用SELECT information_schema来显示information_schema例程中有哪些列:

1 mysql    > SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM  INFORMATION_SCHEMA.COLUMNS
2         -> WHERE TABLE_NAME = 'ROUTINES';// 

  执行以上指令后会输出结果如下:

TABLE_NAMECOLUMN_NAMECOLUMN_TYPE
ROUTINESSPECIFIC_NAME varchar(64)
ROUTINESROUTINE_CATALOGlongtext
ROUTINESROUTINE_SCHEMAvarchar(64)
ROUTINESROUTINE_NAMEvarchar(64)
ROUTINESROUTINE_TYPEvarchar(9)
ROUTINESDTD_IDENTIFIERvarchar(64)
ROUTINESROUTINE_BODYvarchar(8)
ROUTINESROUTINE_DEFINITIONlongtext
ROUTINESEXTERNAL_NAMEvarchar(64)
ROUTINESEXTERNAL_LANGUAGEvarchar(64)
ROUTINESPARAMETER_STYLEvarchar(8)
ROUTINESIS_DETERMINISTICvarchar(3)
ROUTINESSQL_DATA_ACCESSvarchar(64)
ROUTINESSQL_PATHvarchar(64)
ROUTINESSECURITY_TYPEvarchar(7)
ROUTINESCREATEDvarbinary(19)
ROUTINESLAST_ALTEREDvarbinary(19)
ROUTINESSQL_MODElongtext
ROUTINESROUTINE_COMMENTvarchar(64)
ROUTINESDEFINERvarchar(77)

  知道了上面的表结构,就可以查询我们想要得到的信息,如下代码可查看数据库db6中定义的存储过程:

1 mysql    > SELECT COUNT(*) FROM INFORMATION_SCHEMA.ROUTINES      
2         -> WHERE ROUTINE_SCHEMA = 'db6';//    

ROUTINE_DEFINITION列的访问控制

  在INFORMATION_SCHEMA中的ROUTINE_DEFINITION列是由过程或函数组成过程体获得的,因可能存在敏感信息而只对过程创建者可见.

  CURRENT_USER<>INFORMATIN_SCHEMA.ROUTINES.DEFINER:如果对它使用SELECT的用户不是创建它的用户,则MySQL将返回null值,而不是ROUTINE_DEFINITION列.

SHOW PROCEDURE STATUS中的辅助子句

  既然已列出INFORMATION_SCHEMA.ROUTINES中的列,就可以回去解释SHOW PROCEDURE STATUS的新细节:语法是: SHOW PROCEDURE STATUS [WHERE condition]; .特别注意的部分是:在WHERE子句中你必须使用INFORMATION_SCHEMA列的名字,结果显示的是SHOW PROCEDURE STATUS字段的名字.例如:

1 mysql> SHOW PROCEDURE STATUS WHERE Db = 'p';  
2 /*ERROR 1054 (42S22): Unknown column 'Db' in 'where clause'*/
3 mysql> SHOW PROCEDURE STATUS WHERE ROUTINE_NAME = 'p'; 

转载于:https://www.cnblogs.com/free-coder/p/4777417.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值