My sql procedure

  • 1,833 views
Uploaded on

 

More in: Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,833
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
2
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. MySQL 5.0 存储过程 MySQL 5.0 新特性系列 第一部分 MySQL 技术白皮书 Peter Gulutzan March, 2005 奕朋陈:译翻 学大技科子电安西 2005-5-6 内国持支,的目业商何任及涉不,译翻人个于属:明声( )谢谢,处出明 注时载转请,展发 MySQLCopyright 2005, MySQL AB 页 第 1信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL注关的业事 息信些这留保时载转请
  • 2. Table of Contents 目录( 词名有专是都本基为因,了译翻做不录目 ) Introduction ....................................................................................................3 A Definition and an Example ........................................................................3 Why Stored Procedures ................................................................................4 Why MySQL Statements are Legal in a Procedure Body...........................8 Characteristics Clauses ..............................................................................10 Parameters....................................................................................................13 The New SQL Statements ...........................................................................15 Scope ...........................................................................................................16 Loops.............................................................................................................21 Error Handling..............................................................................................29 Cursors .........................................................................................................35 Security .........................................................................................................41 Functions ......................................................................................................43 Metadata........................................................................................................44 Details ...........................................................................................................48 Style...............................................................................................................52 Tips when writing long routines.................................................................63 Bugs ..............................................................................................................64 Feature Requests .........................................................................................65 Resources .....................................................................................................65 Conclusion....................................................................................................66 About MySQL ...............................................................................................66Copyright 2005, MySQL AB 页 第 2信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 3. 息信些这留保时载转请 注关的业事 MySQL 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 信来请误错有如 页 第 3 Copyright 2005, MySQL AB 。受接会也家大信相,惯习的去过们我是这为因,程过储存 pi()用使常经更会面里书本在我。) 如,样一数函的载装预 和来起用使(数函的值回返以可 Mysql SQL 中句语 他其在是二 ,程过储存的说们我是一:种两有”)程例( “的持支 routines MySQL ,说来的确准,)样一序程子的里言语规正像就(序程的中库库书在储存种一是程过储存 A Definition and an Example 定义及实例 。助帮和持支的久长到得以,户用 Mysql 深资的识认你询咨以可,障故现出然仍行运果如但。上脑电的您在行运的常正能将子例 的里这此因。 , , HP-UX Windows Sparc 括包,了 多更持支能时同,本版的高更有经已 OS Mysql ,候时的书本读阅您在。过通试测上版共公 、 在经已都子例的以所 Mysql 5.0.3 Suse 9.2 Linux )本脚关相载下站网 mysql.com 在以可,的版子电是不的读所在现你果如(中序程端户客 mysql 到制复码代将接直以可你,掉去示显统系些这 和 的中子例将会我候时有 "->" "mysql>" Query OK, 0 rows affected (0.00 sec) -> END;// <-- -> /* This procedure does nothing */ -> BEGIN mysql> CREATE PROCEDURE p () :如例。调强示表以边右的 <-- 面页在放号符” “将用会我时同,释注加间落段和行些某在要需则,大较比例实果如 Query OK, 0 rows affected (0.00 sec) mysql> DROP FUNCTION f; :子例个举里这在。样一不本文通普与来起看们他使, Courier 成改体字将,整调行进码代的现出就幕屏的端户客 对会我,时码代际实示演要想我次每 mysql 约定和编程风格 Conventions and Styles约定和编程风格 。握掌能就快很信 相,学去程课着跟要只是但,难很例用个这为认会家大许也前之习学在,例用用实的大较 示展家大给会后最,念概立建家大为的慢慢始开节细个一每从会我,的目的样这到达了为 。识知的要需到学你让子例、题问的单简用,话对行进您与样那家专行内像能书本 这望希。集一第的书丛性特新 MySQL 5.0 绍介是这,”图视构架息信、图视、器发触、程过 储存“了绍介是说来的单简。的写而户用老 的性特新本版 解了要需为是书本 MySQL 5.0 Introduction
  • 4. 息信些这留保时载转请 注关的业事 MySQL 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 信来请误错有如 页 第 4 Copyright 2005, MySQL AB 。已而点优的上以有没是只们它,择选的好很是还处好的程例言语部外用使 SQL ,过不。势优的句语 用使比相言语部外等 或 、 与是就这。包的同不置配 PHP Java C 脑电的号型同不的你为者或,可许置设行执中统系作操在序程为要需不也,包境环行运 加添外额你要需不,上台平何任的持支 在行运以可它道知就你,时程过储存写编Mysql SQL 用你当!的植移以可是程过储存。序程用应是不而辑逻库据数是它为因,响影生产 !件组的用复可是程过储存 !件组的用复可是程过储存 会不程过储存对这,言语的机主了变改你果如下一象想!件组的用复可是程过储存 !件组的用复可是程过储存 。了往来息信的多么那没就间之端户客和器务服时 步一每的务任行执在样这。成完来程过储存的上器务服在存保用使以可就你,务任性复 重的互交户用有没但句语多、环循、查检要需是的理处要需你果如。量流息信络网低 降否能于在却法方要主的度速升提是但。快么那来起行运序程的写编) 如(言语部外 C SQL 像会不程过储存 此因,器译编有没于由。样那的做所)句语理处预( statements Prepared 像就,进改了做上制机存缓在器务服 是就的说以可们我。样一不也验体 Mysql Mysql !快更行运统系使会程过储存 !快更行运统系使会程过储存 的到得户用,势优个这明证上 在能不时暂们我然虽!快更行运统系使会程过储存 !快更行运统系使会程过储存 。读阅你 供可档文的方三第多许有还,户用验经的用雇者或询咨以可你多很有也,念概些这得 获里那人他其 从以可你此因。的同相是往往法语的们它而,在存已早中 他其在 DBMS !术技的证认被经已是程过储存 数函的能功同相是但,的新是它中 在然虽!术技的证认被经已是程过储存 !术技的证认被经已是程过储存 !术技的证认被经已是程过储存Mysql 。做去不得不你 ,因原要需不做样这。来中程过储存到移转)中本脚是或,中) ( UDF 数函义定自户用 ,中序程用应器务服在能可(序程有现把虑考始开该应你而然。路 的过走们他走你带来户用的验经有的量大多很有没也,过用使人何任有没前之此在 ,竟毕 。意注加更要需你时用使在的然自很,能功的新是说来 于对程过储存于由 MySQL Why Stored Procedures 为什么要用存储过程 。的然必是联关的程过储存和器发触为因,器发触——象 对库据数的新绍介将们我时同。节细有所的作工的做程过储存用利以可你绍介会将我面下 束结块句语 END /* end of block */ 句语 INSERT INTO table1 VALUES (variable1);/* statement SQL */ 束结 END IF; /* end of IF IF */ 值赋 SET variable1 = beasts; /* assignment */ ELSE 值赋 SET variable1 = birds; /* assignment */ 始开件条 IF parameter1 = 17 THEN /* start of IF IF */ 明声量变 DECLARE variable1 CHAR(10); /* variables */ 头块句语 BEGIN /* start of block */ 数参 (IN parameter1 INTEGER) /* parameters */ 名程过储存 CREATE PROCEDURE procedure1 /* name */ )释注文中何任添不序程的后此,读阅便方了为:注译( :明声例实的程过储存括包个一是面下 IF 。义定法语的新有句件条 和制控环循,理处常异,量变部局对里这在 SQL SQL 。集句语 的句语 多很括包以可及以,表列数参,字名括包程过储存个一
  • 5. !存保被将程过储存 !存保被将程过储存 ,消撤票支的中理处物事行银示显如例,序程个一了好写编你果如!存保被将程过储存 !存保被将程过储存 这。中库据数在存保式形的码代源以会它 。序程的你到找以可就人的票支解了要想那 。样一的说中论划规的到听上课在你跟能可这联关的义意有程进的据数理处和据数使将 ) 、 如(库据数些某。准标 Mysql !植移以可程过储存 持支全完 !植移以可程过储存 !植移以可程过储存 !植移以可程过储存 SQL 2003 DB2 Mimer 够足予给会将们我。持支不 、 如,的持支不分部有也但。持支样同 Oracle SQL Server 。上 到移转易容更能码代的写编 他其为使,具工和助帮 DBMS Mysql Setting up with MySQL 5.0 设置并开始 设置并开始MySQL 5.0服务 服务 务服 始开来 者或 mysql_fix_privilege_tables 过通 ~/mysql-5.0/scripts/mysql_install_db MySQL 员理管库据数有没果如。装安经已 定假我,分部一的作工备准的习练们我为作 MySQL 5.0 ,事件一掉忘易容很你过不。了装安去己自要需就你,件软他其及以库据数好装安你为 。表的 为名个一有要需你是就那 mysql.proc 要需只( 者或 行运须必你,后本版新最了装安在 mysql_fix_privilege_tables mysql_install_db 个一行运后份身 在用启时同我。作工能不将程过储存然不——)了够就个一中其行运 root SQL :下如,本脚 的式正非 mysql>source/home/pgulutzan/mysql- 5.0/scripts/mysql_prepare_privilege_tables_for_5.sql Starting the MySQL Client 启动 启动MySQL客户端 客户端 是者或本版制进二是的用使你果如,式方他其用使会许也你。式方的端户客 动启我是这 mysql Windows :序程下以行运下录目子他其在会能可你,脑电的统系 pgulutzan@mysqlcom:~> /usr/local/mysql/bin/mysql --user=root Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 1 to server version: 5.0.3-alpha-debug Type help; or h for help. Type c to clear the buffer. 的后陆登份身 以示展会将我,中示演在 root mysql 的大极有我着味意样这,果结的回返端户客 。权特 Check for the Correct Version 核对版本 的用使认确了为 MySQL 的用使我认确法方种两有我。本版询查要们我,的确正是本版的 :本版 是 5.0 SHOW VARIABLES LIKE version; or SELECT VERSION();Copyright 2005, MySQL AB 页 第 5信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 6. :如例 mysql> SHOW VARIABLES LIKE version; +---------------+-------------------+ | Variable_name | Value | +---------------+-------------------+ | version | 5.0.3-alpha-debug | +---------------+-------------------+ 1 row in set (0.00 sec) mysql> SELECT VERSION(); +-------------------+ | VERSION() | +-------------------+ | 5.0.3-alpha-debug | +-------------------+ 1 row in set (0.00 sec) 字数见看当 。作工常正上端户客个这在够能程过储存认确以可就后 5.0.x The Sample "Database" 示例数据库 示例数据库 的骤步个这现实库据数认默为定设后然库据数的新个一建创是事件一第的做要在现 SQL :下如句语 CREATE DATABASE db5; USE db5; :如例 mysql> CREATE DATABASE db5; Query OK, 1 row affected (0.00 sec) mysql> USE db5; Database changed 。表作工的单简个一建创们我后然库据数的际实的据数要重有用使免避要里这在 SQL:下如句语 的骤步个这现实 mysql> CREATE DATABASE db5; Query OK, 1 row affected (0.01 sec) mysql> USE db5; Database changed mysql> CREATE TABLE t (s1 INT); Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO t VALUES (5); Query OK, 1 row affected (0.00 sec) 要需不并里这在为因,单简的表持保要我是因原的做样这。列一了入插中表在只我现发会你 。了杂复够经已身本它为因,表据数的大用使要需不,程过储存授教是而,巧技的据数询查示展Copyright 2005, MySQL AB 页 第 6信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, 注关的业事 MySQL 息信些这留保时载转请
  • 7. 息信些这留保时载转请 注关的业事 MySQL 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 信来请误错有如 页 第 7 Copyright 2005, MySQL AB :况情的面下现出会将时用调在,了做 样这果如,字名的数函建内 MySQL 用使要不意注但,符字个 为制限度长其,符格空括包 64 db5.p1 以可它,开分以可名程过储存。” “如,法方中折的样这”名程过储存 名库据数“ . 取采以可你 。)。吧持支会后以望希:话者译(持支不 是但,)持支 MySQL Oracle DBMS (载重许允 些某。载重致导会将样这为因,字名的同相取程过储存个两给能不 将你中库据数个一同在,字名个一同是’ ‘和’ ‘此因,感敏不写小大对名程过储存 p1 P1 题问的符识标法合:话外题 题问的符识标法合:话外题 题问的符识标法合:话外题 题问的符识标法合:话外题 Digression: Legal Identifiers 。 是字名的程过储存新面上,名程过是分部二第 p1 <-- CREATE PROCEDURE p1 () SELECT * FROM t; // :” CREATE PROCEDURE “ 是分部一第的程过储存句语 SQL <-- CREATE PROCEDURE p1 () SELECT * FROM t; // 。碑程里的要重个这下记中记日的你在好最,话的样这是如假。程过储存个一第的建创 Mysql 用使你是这许也 CREATE PROCEDURE p1 () SELECT * FROM t; // CREATE PROCEDURE Example 创建程序实例 "DELIMITER ;//". :了以可就句语面 ; 下入输,符隔分为作)号分(” “用使复恢要后以果如。样一我跟择选好最你,解理易容 更了为中程课个这在是但,择选来好喜的己自据根以可你。样这欢喜不我但,的号符” “ @ DB2 | 用使中序程 在过见曾我。 “线竖用人有也, “杠斜双过用曾我。符隔分为作串符字 ” ” // 的中序程或句语的你在现出能可太不个一择选要需你此因号分个一要需都个一每以所,句 语多许有中程过储存为因,题问少不生产会这,中程过储存在但,”;“号分用使都们我 来以直一。号符串符字或符字的句语 个一入输成完经已你端户客 知通你是符隔分 SQL mysql mysql> DELIMITER // :如例 DELIMITER // SQL :下如句语 的骤步个这现实,符隔分个一要需们我在现 Pick a Delimiter 选择分隔符 始开表的列一含包只的 为字名个这从将们我,库据数例示是就这t
  • 8. mysql> CALL pi(); Error 1064 (42000): You have a syntax error. mysql> CALL pi (); Error 1305 (42000): PROCEDURE does not exist. 上加后名数函的用调在须必你但,数函的 叫字名个一是的用调我,里子例个一第的面上在 pi 。样那子例个二第像就,格空 CREATE PROCEDURE p1 () SELECT * FROM t; // <-- 。”表列数参“是”)(“中其 中子例。数参加添内号括在要需常通。表列数参是分部三第的句语 CREATE PROCEDURE 。的须必是这而然,号括空入键要需只我以所——的空是表列数参此因,数参有没程过储存的 CREATE PROCEDURE p1 () SELECT * FROM t; // <-- "SELECT * FROM t;" 。体主的程过储存是 句语中体程过。句语 的般一是,体主的程过储存是它,了分部个一后最的句语了到后然 SQL 。号分个这写不以可时) (号符束结句语有面后果如,号分个一含包 "SELECT * FROM t;" // 的用使家大是词个这) (为因,事好件是会将体主的序程做叫分部这把我得记还你果如 body 使以所。示演了为是只里这,中程过储存在用句语 将会不们我常通。语术的上术技 SELECT 。作工常正否是序程出看的好更时用调在能,句语的样这用 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 。件组选可即,的心核非为义定个这把中准Copyright 2005, MySQL AB 页 第 8信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 9. 息信些这留保时载转请 注关的业事 MySQL 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 信来请误错有如 页 第 9 Copyright 2005, MySQL AB 。句子的用可多很有会将们我前件部杂复写在样那 。句子的在存经已变改者或,句子条一加都次每,习练的列系一有就们我快很是但。单 简当相这说己自对能你望希我。了楚清经已”法方程过用调和建创“点识知的要主,了好 "SELECT * FROM t;". :句语面下了行执你于当相就程过 用调你,以所 p1 mysql> SELECT * FROM t; // :样一果效行执的句语面下和 mysql> CALL p1() // 式方现实他其 式方现实他其 式方现实他其 式方现实他其 2. "SELECT * FROM t;" 是句语的中程过为因 Query OK, 0 rows affected (0.03 sec) 1 row in set (0.03 sec) +------+ | 5| +------+ | s1 | +------+ mysql> CALL p1() // t p1容内的表 了回返幕屏是果结,时程过 的面里子例用调你当的须必是号括,调强次一再号括个容内的表 了回返幕屏是果结,时程过 的面里子例用调你当的须必是号括,调强次一再号括个容内的表 了回返幕屏是果结,时程过 的面里子例用调你当的须必是号括,调强次一再号括个容内的表 了回返幕屏是果结,时程过 的面里子例用调你当的须必是号括,调强次一再号括个 CALL 一及以名程过你和 是就部全的入输要需所你,了程过储存个一用调以可就们我在现 一及以名程过你和 是就部全的入输要需所你,了程过储存个一用调以可就们我在现 一及以名程过你和 是就部全的入输要需所你,了程过储存个一用调以可就们我在现 一及以名程过你和 是就部全的入输要需所你,了程过储存个一用调以可就们我在现 1. Call the Procedure 调用存储过程 MySQL 。所场作工的程过是就库据数认默定假 为因,的法非是也 "CREATE PROCEDURE db5.p1 () DROP DATABASE db5//" 句语 似类是但, "USE database" DROP FUNCTION, CREATE TRIGGER, DROP TRIGGER. 用使以可你过不 CREATE PROCEDURE, ALTER PROCEDURE, DROP PROCEDURE, CREATE FUNCTION, MySQL 5.0 :的法非是中体程过在,句语的新全说来 对些这面下 CREATE PROCEDURE p2 () DELETE FROM t; // CREATE PROCEDURE p1 () :的法非是 就子例的面下如例。句语作操库据数的作操表或程例对有能不是就,束约个一有中体程过在
  • 10. 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 。意注不在现在少至,个Copyright 2005, MySQL AB 页 第 10信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 11. 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 SQL SECURITY 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 .Copyright 2005, MySQL AB 页 第 11信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 12. 一些题外话 : 用调 用调 用调 用调 果结的 果结的 果结的 果结的 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 。数机随的得获望期们我回返行执被句语 : 的变改会不 的变改会不 的变改会不 的变改会不 sql_mode mysql> set sql_mode=ansi // mysql> create procedure p3()selecta||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"Copyright 2005, MySQL AB 页 第 12信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 13. 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 。出输为作以可也入输为作能既,数参个一有中子例个四第,数参出输个一有中子例个三第Copyright 2005, MySQL AB 页 第 13信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 14. 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 wont CALL this. 用调被会不将句语个这 */Copyright 2005, MySQL AB 页 第 14信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 15. 的中言语 和块句语 个这。块 是就造构的体程过成完 BEGIN/END BEGIN/END Pascal BEGIN/END 子例个这在。句语条多装封去块用使以可们我。的似相很是架框的言语 和,的同相本基是 C 程过的你果如。句语 和 些一了成完后然,句语的量变话会定设条多了用使们我,中 insert select 这在,句语合复为称被也块 。了块 要需就你么那,句语条多有中体 BEGIN/END BEGIN/END 。制控程流和义定量变行进以可你里 The New SQL Statements 新SQL语句 语句 Variables 变量 是令指的量变明声中句语合复在 DECLARE 。 (1) Example with two DECLARE statements 个两 个两 个两 个两 DECLARE 子例的句语 子例的句语 子例的句语 子例的句语 CREATE PROCEDURE p8 () BEGIN DECLARE a INT; DECLARE b INT; SET a = 5; SET b = 5; INSERT INTO t VALUES (a); SELECT s1 * a FROM t WHERE s1 >= b; END; // /* I wont CALL this */ :注译(已而了义定内块 在是只你,义定的正真是不并量变的义定中程过在 BEGIN/END 在的楚清须必你 符饰修用使能不,样一不量变话会和量变些这意注 。)参形是就也 @ 变话会用使能何任在能就你,明声旦一量变 。型类的们它和量变明声中块 BEGIN/END 。用使方地的名列、字文、量 子例的句语定设和句子认默有没 子例的句语定设和句子认默有没 子例的句语定设和句子认默有没 子例的句语定设和句子认默有没 (2) Example with no DEFAULT clause and SET statement CREATE PROCEDURE p9 () BEGIN DECLARE a INT /* there is no DEFAULT clause */; DECLARE b INT /* there is no DEFAULT clause */; SET a = 5; /* there is a SET statement */ SET b = 5; /* there is a SET statement */ INSERT INTO t VALUES (a); SELECT s1 * a FROM t WHERE s1 >= b; END; // /* I wont CALL this */ 为值始初的量变么那,句子的认默有没果如。法方的量变化始初多很有 NULL何任在以可你。 SET 。值赋量变给句语 用使候时Copyright 2005, MySQL AB 页 第15信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, MySQL注关的业事 息信些这留保时载转请
  • 16. (3) Example with DEFAULT clause 有含 有含 有含 有含 子例的句子 子例的句子 子例的句子 子例的句子 DEFAULT CREATE PROCEDURE p10 () BEGIN DECLARE a, b INT DEFAULT 5; INSERT INTO t VALUES (a); SELECT s1 * a FROM t WHERE s1 >= b; END; // 了用使里这在。的样一是还果结是但,变改些一了做里这在们我 DEFAULT 初定设来句子 。了开分现实的句语 和 把要需不就这,值始 DECLARE SET 子例的用调 子例的用调 子例的用调 子例的用调 (4) Example of CALL mysql> CALL p10() // +--------+ | s1 * a | +--------+ | 25 | | 25 | +--------+ 2 rows in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) 作工常正能程过了示显果结 域用作 域用作 域用作 域用作 (5) Scope CREATE PROCEDURE p11 () BEGIN DECLARE x1 CHAR(5) DEFAULT outer; BEGIN DECLARE x1 CHAR(5) DEFAULT inner; SELECT x1; END; SELECT x1; END; // 同。的法合是这然当,块 的套嵌有中子例。题问的域用作下一论讨来们我在现 BEGIN/END 优的高更有享内域用作其在量变的部内。的法合是也样这, 是都字名,量变个两含包时 x1 因,了见可再不量变,外域用作其在经已时此,失消量变部内,时句语 到行执当。权先 END 派指值其将者或数参TUO过通以可你是但,量变的了明声个这到找能不也再外程过储存在此 值其存保来量变话会给Copyright 2005, MySQL AB 页 第16信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, 注关的业事 MySQL 息信些这留保时载转请
  • 17. :程过的子例域用作用调 mysql> CALL p11()// +-------+ | x1 | +-------+ | inner | +-------+ +-------+ | x1 | +-------+ | outer | +-------+ 个一第时果结的到看们我 SELECT 量变的层二第到索检个二第,量变的层内最到索检句语 Conditions and IF-THEN-ELSE 条件式和 条件式和IF-THEN-ELSE 1. :子例的式件条含包些一写以可们我在现 :子例的式件条含包些一写以可们我在现 :子例的式件条含包些一写以可们我在现 :子例的式件条含包些一写以可们我在现 CREATE PROCEDURE p12 (IN parameter1 INT) BEGIN DECLARE variable1 INT; SET variable1 = parameter1 + 1; IF variable1 = 0 THEN INSERT INTO t VALUES (17); END IF; IF parameter1 = 0 THEN UPDATE t SET s1 = s1 + 1; ELSE UPDATE t SET s1 = s1 + 2; END IF; END; // 是个一另, 句语 是个一,句语 个两有面里。程过的句语 含包个一是里这 IF IF IF END IF IF 更能你让单简其使量尽会我但,程过的杂复用使里这在以可们我。 ELSE END IF 句语 句语 。楚清弄易容 2. CALL p12 (0) // 样这, 为值入传,程过个这用调们我 0 parameter1 。 为将值的 0Copyright 2005, MySQL AB 页 第 17信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 18. 3. CREATE PROCEDURE p12 (IN parameter1 INT) BEGIN DECLARE variable1 INT; SET variable1 = parameter1 + 1; <-- IF variable1 = 0 THEN INSERT INTO t VALUES (17); END IF; IF parameter1 = 0 THEN UPDATE t SET s1 = s1 + 1; ELSE UPDATE t SET s1 = s1 + 2; END IF; END; // 量变里这 variable1 为值赋被 parameter1 量变后行执以所,值的 加 1 variable1 。为 1 4. CREATE PROCEDURE p12 (IN parameter1 INT) BEGIN DECLARE variable1 INT; SET variable1 = parameter1 + 1; IF variable1 = 0 THEN <-- INSERT INTO t VALUES (17); END IF; IF parameter1 = 0 THEN UPDATE t SET s1 = s1 + 1; ELSE UPDATE t SET s1 = s1 + 2; END IF; END; // 量变为因 variable1 件条此因, 为值 1 "if variable1 = 0" …… ,假为 IF END IF 。行执被有没,过跳被 5. CREATE PROCEDURE p12 (IN parameter1 INT) BEGIN DECLARE variable1 INT; SET variable1 = parameter1 + 1; IF variable1 = 0 THEN INSERT INTO t VALUES (17); END IF; IF parameter1 = 0 THEN <-- UPDATE t SET s1 = s1 + 1; ELSE UPDATE t SET s1 = s1 + 2; END IF; END; //Copyright 2005, MySQL AB 页 第 18信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 19. 了行执被句语间中是于,真为果结断判,件条 个二第到 IF 6. CREATE PROCEDURE p12 (IN parameter1 INT) BEGIN DECLARE variable1 INT; SET variable1 = parameter1 + 1; IF variable1 = 0 THEN INSERT INTO t VALUES (17); END IF; IF parameter1 = 0 THEN UPDATE t SET s1 = s1 + 1; <-- ELSE UPDATE t SET s1 = s1 + 2; END IF; END; // 条一下则, 为值 果如。行执被句语 parameter1 , 于等值 0 数参为因 UPDATE parameter1 NULL 行两, 用调们我果如以所, 值含包都们他,行两有中 表在现 行执被将句语 UPDATE t 5 p12 6 。 成变会值的 7. mysql> CALL p12(0)// Query OK, 2 rows affected (0.28 sec) mysql> SELECT * FROM t// +------+ | s1 | +------+ | 6| | 6| +------+ 2 rows in set (0.01 sec) 。样那的望期所们我是也果结 CASE 指令 1. CREATE PROCEDURE p13 (IN parameter1 INT) BEGIN DECLARE variable1 INT; SET variable1 = parameter1 + 1; CASE variable1 WHEN 0 THEN INSERT INTO t VALUES (17); WHEN 1 THEN INSERT INTO t VALUES (18); ELSE INSERT INTO t VALUES (19); END CASE; END; //Copyright 2005, MySQL AB 页 第 19信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 20. 用使以可们我断判的假真件条多更行进要需果如 CASE 。句语 CASE 。单简样一 和用使句语 IF :子例的面上考参以可们我 2. mysql> CALL p13(1)// Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM t// +------+ | s1 | +------+ | 6| | 6| | 19 | +------+ 3 rows in set (0.00 sec) 。中 表到入插被 值,子例面上如, 值入传,后程过行执 1 19 t Question 题问 题问 题问 题问 ?么什是用作的 : CALL p13(NULL) // 题问 CALL?作动些那了做句语 个这:个一另 。出做内秒 在,断判码代据根以可也,么什了做 察观后行执过通以可你 SELECT 5 Answer 案答 案答 案答 案答 mysql> CALL p13(NULL)// Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM t// +------+ | s1 | +------+ | 6| | 6| | 19 | | 19 | +------+ 4 rows in set (0.00 sec) 值的 量变是因原。录记的 值数含包条一另了入插 p13 ,时 用调你当是案答 MySQL 19 variable1 ,来出不答回你果如。义意有家大对这望希。了行执被就分部 的句语 , 为 NULL CASE ELSE 。走下向续继以可们我,题问有没Copyright 2005, MySQL AB 页 第 20信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL注关的业事 息信些这留保时载转请
  • 21. Loops 循环语句 WHILE ... END WHILE LOOP ... END LOOP REPEAT ... END REPEAT GOTO 及以环循 ,环循 :式方环循的准标种三有们我。环循些一建创会将们我面下 WHILE LOOP 使就了用,吧用要不好最:语者译( REPEAT :式方环循的准标非种一有还。环循 GO TO 。)乱混程流 WHILE ... END WHILE CREATE PROCEDURE p14 () BEGIN DECLARE v INT; SET v = 0; WHILE v < 5 DO INSERT INTO t VALUES (v); SET v = v + 1; END WHILE; END; // 。法语的新多很握掌要需不此因,似相句语 跟它,式方种这欢喜很我。式方的环循 WHILE 是这 IF 。出退会将环循候时的 于大 量变当,间之 INSERT SET 和 在句语 和 WHILE 的里这 END WHILE v 5 而, 为值量变认默,化始初有没果如,误错的见常个一止防了为使句语 "SET v = 0;" 用使 NULL NULL 。 为都果结作操值何任和 NULL WHILE ... END WHILE example mysql> CALL p14()// Query OK, 1 row affected (0.00 sec) 果结的 程过用调是就上以 p14 是回返统系注关用不 "one row affected" 是还 "five rows affected" 后最对只数计的里这为因, 。数计行进作动 个一 INSERTCopyright 2005, MySQL AB 页 第 21信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL注关的业事 息信些这留保时载转请
  • 22. WHILE ... END WHILE example: CALL mysql> select * from t; // +------+ | s1 | +------+ .... | 0| | 1| | 2| | 3| | 4| +------+ 9 rows in set (0.00 sec) 。行 了入插中库据数向序程到看以可后用调 5 REPEAT ... END REPEAT CREATE PROCEDURE p15 () BEGIN DECLARE v INT; SET v = 0; REPEAT INSERT INTO t VALUES (v); SET v = v + 1; UNTIL v >= 5 END REPEAT; END; // ,果结查检后行执在它于在别区。样一环循 REPEAT 面前和能功,子例的环循 个一是这 WHILE WHILE )吧 于同等能可:语者译(。查检前行执是则 而 DO WHILE REPEAT ... END REPEAT: look at the UNTIL: UNTIL的作用 : 的作用 CREATE PROCEDURE p15 () BEGIN DECLARE v INT; SET v = 0; REPEAT INSERT INTO t VALUES (v); SET v = v + 1; UNTIL v >= 5 <-- END REPEAT; END; // 到意注 UNTIL 。好更号分的外额上加你然当,号分写不以可里这在,号分有没面后句语Copyright 2005, MySQL AB 页 第 22信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 23. REPEAT ... END REPEAT: calling :调用 mysql> CALL p15()// Query OK, 1 row affected (0.00 sec) mysql> SELECT COUNT(*) FROM t// +----------+ | COUNT(*) | +----------+ | 14 | +----------+ 1 row in set (0.00 sec) 录记行 了入插又后程过 用调到看以可们我 p15 5 LOOP ... END LOOP CREATE PROCEDURE p16 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN LEAVE loop_label; END IF; END LOOP; END; // 是上以 LOOP 和点这,件条始初要需不环循 。子例的环循 LOOP WHILE 它时同,似相环循 和又 REPEAT 。件条束结要需不也样一环循 LOOP ... END LOOP: with IF and LEAVE 包含 和LEAVE的LOOP循环 包含IF和 的 循环 CREATE PROCEDURE p16 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN <-- LEAVE loop_label; END IF; END LOOP; END; // 循开离是义意的句语 里这。句语 IF 含包中句语 在,句语 入加部内环循在 IF LEAVE LEAVE 一进面后在会我题问号标的句语环循于关,号标句语环循加 LEAVE LEAVE是法语的 。环 。解讲步Copyright 2005, MySQL AB 页 第 23信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 24. LOOP ... END LOOP: calling :调用 mysql> CALL p16()// Query OK, 1 row affected (0.00 sec) mysql> SELECT COUNT(*) FROM t// +----------+ | COUNT(*) | +----------+ | 19 | +----------+ 1 row in set (0.00 sec) 。中 表入插被行 另是果结,后 程过用调 p16 5 t Labels 标号 CREATE PROCEDURE p17 () label_1: BEGIN label_2: WHILE 0 = 1 DO LEAVE label_2; END WHILE; label_3: REPEAT LEAVE label_3; UNTIL 0 =0 END REPEAT; label_4: LOOP LEAVE label_4; END LOOP; END; // 我。子例的程过的号标句语个 含包个一有里这在现。号标句语了用使我中子例环循个一后最 4 的法合在能只号标句语,号标句语用使前句语 者或 BEGIN 、 WHILE REPEAT 、 在以可们 LOOP 。句语合复或句语的 为义定名号标句语开离着味意 此因。用使面前句语 "LEAVE label_3" label_3 End Labels 标号结束符 CREATE PROCEDURE p18 () label_1: BEGIN label_2: WHILE 0 = 1 DO LEAVE label_2; END WHILE label_2; label_3: REPEAT LEAVE label_3; UNTIL 0 =0 END REPEAT label_3 ; label_4: LOOP LEAVE label_4; END LOOP label_4 ; END label_1 ; // 。用有分十是不并符束结号标些这。样一用使时头开在和,号标句语用使时束结句语在以可也你 ,惯习程编的好良有了为然当样一字名号标的义定始开和须必们他,要需你果如。的选可是们它 。符束结号标用使是还好最,读阅人他便方Copyright 2005, MySQL AB 页 第 24信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 注关的业事 MySQL 息信些这留保时载转请
  • 25. LEAVE and Labels 跳出和标号 CREATE PROCEDURE p19 (parameter1 CHAR) label_1: BEGIN label_2: BEGIN label_3: BEGIN IF parameter1 IS NOT NULL THEN IF parameter1 = a THEN LEAVE label_1; ELSE BEGIN IF parameter1 = b THEN LEAVE label_2; ELSE LEAVE label_3; END IF; END; END IF; END IF; END; END; END;// LEAVE 。句语合复的杂复出跳序程使句语 ITERATE 代迭 代迭 代迭 代迭 是标目果如 ITERATE 到用须必就,话的句语)代迭( LEAVE 句语 CREATE PROCEDURE p20 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP IF v = 3 THEN SET v = v + 1; ITERATE loop_label; END IF; INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN LEAVE loop_label; END IF; END LOOP; END; // 中言语 像点有它 ,用引环循的部内环循在是也样一句语 ITERATE 和句语)代迭( LEAVE C 思意)代迭( ,号标句语合复用引,中句语合复在现出以可它样同,” Continue “的 ITERATE 。句语合复始开新重是 :环循的程过代迭要需个是这,环循个这面下察观并动启们我那Copyright 2005, MySQL AB 页 第 25信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 26. ITERATE: Walking through the loop 环循入深 环循入深 环循入深 环循入深 CREATE PROCEDURE p20 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP <-- IF v = 3 THEN SET v = v + 1; ITERATE loop_label; END IF; INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN LEAVE loop_label; END IF; END LOOP; END; // 。来起行运环循的号标了义定经已个这让 ITERATE: Walking through the loop CREATE PROCEDURE p20 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP IF v = 3 THEN <-- SET v = v + 1; ITERATE loop_label; END IF; INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN LEAVE loop_label; END IF; END LOOP; END; // v 。 到加增它把们我后然, 成变值的 3 4 ITERATE: walking through the loop CREATE PROCEDURE p20 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP IF v = 3 THEN SET v = v + 1; ITERATE loop_label; <-- END IF; INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THENCopyright 2005, MySQL AB 页 第 26信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 27. LEAVE loop_label; END IF; END LOOP; END; // 始开后然 ITERATE 。程过)代迭( ITERATE: walking through the loop CREATE PROCEDURE p20 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP <-- IF v = 3 THEN SET v = v + 1; ITERATE loop_label; END IF; INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN LEAVE loop_label; END IF; END LOOP; END; // 的里这 ITERATE 。部头的环循了到回又环循让)代迭( ITERATE: walking through the loop CREATE PROCEDURE p20 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP IF v = 3 THEN SET v = v + 1; ITERATE loop_label; END IF; INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN LEAVE loop_label; <-- END IF; END LOOP; END; // 行执将序程,时 为变值的 当 v 5 LEAVE 句语 ITERATE: walking through the loop CREATE PROCEDURE p20 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP IF v = 3 THEN SET v = v + 1;Copyright 2005, MySQL AB 页 第 27信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 28. ITERATE loop_label; END IF; INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN LEAVE loop_label; END IF; END LOOP; END; // <-- LEAVE 。步一后最的句语合复达到令指行运使,环循出跳是就果结的 GOTO CREATE PROCEDURE p... BEGIN ... LABEL label_name; ... GOTO label_name; ... END; 号标立建里这在且而,句语 准标是不这然虽。句语 用使以可中程过储存的 MySQL GOTO SQL 我以所,汰淘被慢慢会句语个这,容兼 他其和了为于由。样一不的中例惯和也法方的 DBMS MySQL 。及提有没中册手考参 在们 Grand combination 合组大 合组大 合组大 合组大 CREATE PROCEDURE p21 (IN parameter_1 INT, OUT parameter_2 INT) LANGUAGE SQL DETERMINISTIC SQL SECURITY INVOKER BEGIN DECLARE v INT; label goto_label; start_label: LOOP IF v = v THEN LEAVE start_label; ELSE ITERATE start_label; END IF; END LOOP start_label; REPEAT WHILE 1 = 0 DO BEGIN END; END WHILE; UNTIL v = v END REPEAT; GOTO goto_label; END;// 块 ,数参性特,表列数参括包,法语有所的讲前之们我了含包句语的中子例面上 BEGIN/END 是这。 , , , , , IF, ,明声量变,句语合复 WHILE LOOP REPEAT LEAVE ITERATE GOTO 。法合分十却法语的面里是但。环循的尽无有面里为因,它行运会不我,程过储存的谬荒个一 。西东的新多更触接要将们我面下。句语明声量变和制控程流的新是些这Copyright 2005, MySQL AB 页 第 28信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 29. Error Handling 异常处理 异常处理 要摘息信的页几面后 例样题问 Sample Problem 器理处常异 Handlers 件条 Conditions 理处常异是的讲要在现们我,了好 录记障故:例样题问 录记障故:例样题问 录记障故:例样题问 录记障故:例样题问 1. Sample Problem: Log Of Failures 很是例样题问的理处错出示展来用们我中件文志日在录记其将能望希我,时败失 INSERT 当 的误错些这下记中件文个一另在想我,时败失 当。录记的误错到得望希我。的通普INSERT 束约的联关键外反违将它是因原的趣兴感别特入插对我。等因原错出,间时错出如例,息信 2. Sample Problem: Log Of Failures (2) mysql> CREATE TABLE t2 s1 INT, PRIMARY KEY (s1)) engine=innodb;// mysql> CREATE TABLE t3 (s1 INT, KEY (s1), FOREIGN KEY (s1) REFERENCES t2 (s1)) engine=innodb;// mysql> INSERT INTO t3 VALUES (5);// ... ERROR 1216 (23000): Cannot add or update a child row: a foreign key constraint fails )息信错出的统系是的示显里这( 打是查检联关键外此因, 是的用使们我。表键外个一及以,表键主个一建创要始开我 InnoDB 很以可下件条种这然当。败失会将作动,时值的中表键主非入插中表键外向我当后然。的开 1216 。 号误错到找快 3. Sample Problem: Log Of Failures CREATE TABLE error_log (error_message CHAR(80))// 。表的误错储存时错出作动入插做在个一立建是就步一下 4. Sample Problem: Log Of Errors CREATE PROCEDURE p22 (parameter1 INT) BEGIN DECLARE EXIT HANDLER FOR 1216 INSERT INTO error_log VALUES (CONCAT(Time: ,current_date, . Foreign Key Reference Failure For Value = ,parameter1)); INSERT INTO t3 VALUES (parameter1); END;// 意。的常异理处来用是 句语个一第的里这。序程的们我是就面上 DECLARE EXIT HANDLER 功成作动当是思意 。行一入插中表录记误错在会将序程个这,了生发 误错果如是思 1215 EXIT 。句语合复个这出退后交提Copyright 2005, MySQL AB 页 第 29信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 30. 5. Sample Problem: Log Of Errors CALL p22 (5) // 息信误错有没是但。现出中表键主在有没并值 为因,常正很这,败失会程过储存个这用调 5 录记中表 是但,西东何任加增有没中表 。了中程过在含包经已理处错出为因回返 t3 error_log 。败失作动 们我诉告就这,息信些一了下 INSERT into table t3 DECLARE HANDLER syntax 声明异常处理的语法 声明异常处理的语法 异常 DECLARE { EXIT | CONTINUE } HANDLER FOR { error-number | { SQLSTATE error-string } | condition } SQL statement ,器理处种两许允 。码代的发触动自后错出序程当段一是就也,法用的理处误错是就面上 MySQL ,理处 ,的示演要将们我是就种一另。种这是就的用所才刚们我,理处 是种一 EXIT CONTINUE 出有没就句语合复个这么那,行运续继然仍序程主原,后行执它于在同不,似类理处 跟它 EXIT 。了口 子例理处 子例理处 子例理处 子例理处 1. DECLARE CONTINUE HANDLER example CONTINUE CREATE TABLE t4 (s1 int,primary key(s1));// CREATE PROCEDURE p23 () BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE 23000 SET @x2 = 1; SET @x = 1; INSERT INTO t4 VALUES (1); SET @x = 2; INSERT INTO t4 VALUES (1); SET @x = 3; END;// 的上册手考参 MySQL是这 CONTINUE 。里这到贝拷它把我以所,好分十子例个这,子例的理处 出看以可们我子例个这过通 CONTINUE 。的作工何如是理处 2. DECLARE CONTINUE HANDLER 理处常异 理处常异 理处常异 理处常异 CONTINUE 明声 明声 明声 明声 CREATE TABLE t4 (s1 int,primary key(s1));// CREATE PROCEDURE p23 () BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE 23000 SET @x2 = 1; <-- SET @x = 1; INSERT INTO t4 VALUES (1); SET @x = 2; INSERT INTO t4 VALUES (1); SET @x = 3; END;// 为将我次这 SQLSTATE ?吗 码代误错 的用使们我面前得记还。序程理处个一义定值 MySQL 1216 的里这上实事 23000SQLSTATE。了用调被就错出束约键主或错出束约键外当,的用常更是Copyright 2005, MySQL AB 页 第 30信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 注关的业事 MySQL 息信些这留保时载转请
  • 31. 3. DECLARE CONTINUE HANDLER CREATE TABLE t4 (s1 int,primary key(s1));// CREATE PROCEDURE p23 () BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE 23000 SET @x2 = 1; SET @x = 1; <-- INSERT INTO t4 VALUES (1); SET @x = 2; INSERT INTO t4 VALUES (1); SET @x = 3; END;// 是句语的行执个一第的程过储存个这 "SET @x = 1" 。 4. DECLARE CONTINUE HANDLER example CREATE TABLE t4 (s1 int,primary key(s1));// CREATE PROCEDURE p23 () BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE 23000 SET @x2 = 1; SET @x = 1; INSERT INTO t4 VALUES (1); SET @x = 2; INSERT INTO t4 VALUES (1); <-- SET @x = 3; END;// 。中表键主到入插被 值后行运 1 5. DECLARE CONTINUE HANDLER CREATE TABLE t4 (s1 int,primary key(s1));// CREATE PROCEDURE p23 () BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE 23000 SET @x2 = 1; SET @x = 1; INSERT INTO t4 VALUES (1); SET @x = 2; <-- INSERT INTO t4 VALUES (1); SET @x = 3; END;// 。 为变值的 后然 @x 2 6. DECLARE CONTINUE HANDLER example CREATE TABLE t4 (s1 int,primary key(s1));// CREATE PROCEDURE p23 () BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE 23000 SET @x2 = 1; SET @x = 1;Copyright 2005, MySQL AB 页 第31信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 32. INSERT INTO t4 VALUES (1); SET @x = 2; INSERT INTO t4 VALUES (1); <-- SET @x = 3; END;// 。制限性一唯有键主为因,了败失但,值数入插中表键主往次再试尝序程后然 7. DECLARE CONTINUE HANDLER example CREATE TABLE t4 (s1 int,primary key(s1));// CREATE PROCEDURE p23 () BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE 23000 SET @x2 = 1; <-- SET @x = 1; INSERT INTO t4 VALUES (1); SET @x = 2; INSERT INTO t4 VALUES (1); SET @x = 3; END;// 语的理处误错是句语的行执个一下。理处误错行进始开,发触被序程理处误错,败失入插于由 @x2 2 。 为设被 ,句 8. DECLARE CONTINUE HANDLER example CREATE TABLE t4 (s1 int,primary key(s1));// CREATE PROCEDURE p23 () BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE 23000 SET @x2 = 1; SET @x = 1; INSERT INTO t4 VALUES (1); SET @x = 2; INSERT INTO t4 VALUES (1); SET @x = 3; <-- END;// 是这为因,束结有没并里这到 CONTINUE ,后之句语入插的败失到回返行执以所。理处常异 。作动 为定设 将行执续继@x 3 9. DECLARE CONTINUE HANDLER example mysql> CALL p23()// Query OK, 0 rows affected (0.00 sec) mysql> SELECT @x, @x2// +------+------+ | @x | @x2 | +------+------+ |3 |1 | +------+------+ 1 row in set (0.00 sec) 以可里这从 。 为,值的 察观 , 是道知以可的定确很,值的 察观们我后程过行运 @x 3 @x2 1 让,器理处误错整调去间时点花以可家大。行进路思的们我照按全完,误无行运序程断判 ,乱紊很序程来起看样那然虽,方地的误错 现出能可在放是不而,部首的段句语在放查检 。楚清很也全安很码代的样这是但。觉感的去跳来跳Copyright 2005, MySQL AB 页 第 32信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 33. 1. DECLARE CONDITION CREATE PROCEDURE p24 () BEGIN DECLARE `Constraint Violation` CONDITION FOR SQLSTATE 23000; DECLARE EXIT HANDLER FOR `Constraint Violation` ROLLBACK; START TRANSACTION; INSERT INTO t2 VALUES (1); INSERT INTO t2 VALUES (1); COMMIT; END; // 误错者或 给可你上实事。的改修上础基的面前在,子例的理处误错个一外另是这 SQLSTATE 我:的现实么怎是它看看面下。了字名的义定己自用使中理处在以可就你,字名的他其码代 t2, 滚回( ) 会都作操入插的表个这对以所,表 InnoDB 为义定 表把 ROLLBACK ROLLBACK 误错 致导会值的样同个两入插键主对为因。的生发会好恰是也)务事滚回( SQLSTATE 23000 。误错束约是 SQLSTATE 23000 里这,生发 2. DECLARE CONDITION 件条明声 件条明声 件条明声 件条明声 CREATE PROCEDURE p24 () BEGIN DECLARE `Constraint Violation` CONDITION FOR SQLSTATE 23000; DECLARE EXIT HANDLER FOR `Constraint Violation` ROLLBACK; START TRANSACTION; INSERT INTO t2 VALUES (1); INSERT INTO t2 VALUES (1); COMMIT; END; // 致导会误错束约个这 ROLLBACK 和)务事滚回( SQLSTATE 23000 。生发误错 3. DECLARE CONDITION mysql> CALL p24()// Query OK, 0 rows affected (0.28 sec) mysql> SELECT * FROM t2// Empty set (0.00 sec) 。录记何任入插有没 表到看们我果结面上从,么什是果结看看程过储存个这用调们我 t2 。的要想们我是正这。了滚回都务事部全 4. DECLARE CONDITION mysql> CREATE PROCEDURE p9 () -> BEGIN -> DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END; -> DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END; -> DECLARE EXIT HANDLER FOR SQLWARNING BEGIN END; -> END;// Query OK, 0 rows affected (0.00 sec) :件条的明声预个三是里这 NOT FOUND (行到不找 ), SQLEXCEPTION (误错 ),Copyright 2005, MySQL AB 页 第33信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, MySQL注关的业事 息信些这留保时载转请
  • 34. 。用使以可就件条明声要需不此因,的明声预是们它为因。 释注或告警 SQLWARNING ( ) 到得会将你, :明声的样这做去你果如过不 "DECLARE SQLEXCEPTION CONDITION ..." 。示提息信误错 Cursors 游标 :要摘能功现实标游 DECLARE cursor-name CURSOR FOR SELECT ...; OPEN cursor-name; FETCH cursor-name INTO variable [, variable]; CLOSE cursor-name; 是但,现实的整完有没并还法语标游的中程过储存的们我然虽。了标游眼着始开们我在现 。标游闭关,取读里标游从,标游开打,标游明声如务事的本基成完以可经已 1. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; OPEN cur_1; REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; END;// 。子例新的程过储存的标游含包下一看们我 2. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; <-- DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; OPEN cur_1; REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; END;// ,明声量变行进要先首。的要重分十是序顺,下一说带附。量变个三了明声始开程过个这 ,明声序顺按有没你果如。器理处误错明声是才面后再,标游明声后随,件条明声后然 。息信误错示提会统系Copyright 2005, MySQL AB 页 第34信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL注关的业事 息信些这留保时载转请
  • 35. 3. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; <-- DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; OPEN cur_1; REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; END;// 标游了明声步二第序程 。多不差 式入嵌和这道知就,话的 式入嵌过用使你果如, cur_1 SQL SQL 4. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND <-- SET b = 1; <-- OPEN cur_1; REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; END;// 个这。明声的器理处误错是的行进后最 CONTINUE和码代误错 用引有没理处SQL SQLSTATE 。值 和这,值回返统系 是的用使它 NOT FOUND 。的样一是 SQLSTATE 02000 5. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; OPEN cur_1; <-- REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; END;//Copyright 2005, MySQL AB 页 第 35信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 36. 是句语的行执可个一第程过 OPEN cur_1 与它, SELECT s1 FROM t 行执将程过 ,的联关是句语 。集果结个一回返, SELECT s1 FROM t 6. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; OPEN cur_1; REPEAT FETCH cur_1 INTO a; <-- UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; END;// 多有中 表而然,值的来出索检中集果结的生产 FETCH 从行一得获会句语 个一第里这 SELECT t 。内块环循在句语为因是这然当,次多行执被会句语个这此因,行 7. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; <-- OPEN cur_1; REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; END;// 当后最 MySQL 的 FETCH ,时行得获有没 CONTINUE 。 为值赋 量变将,发触被理处 b 1 8. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; OPEN cur_1; REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; <-- SET return_val = a; END;//Copyright 2005, MySQL AB 页 第36信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL注关的业事 息信些这留保时载转请
  • 37. ,标游闭关码代写编己自以可们我里这在。束结环循,真为就件条 UNTIL b=1 步一这了到 的统系赖依太要不好最是但,标游闭关动自时束结句语合复在会统系,行执统系由以可也 。)信可不,样一 的 跟能可这:注译(为行闭关动自 Java Gc 9. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; OPEN cur_1; REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; <-- END;// 。用使能仍果结的后束结程过在样这,量变部局个一了派指数参出输为们我中程例个这 10. Cursor Example CREATE PROCEDURE p25 (OUT return_val INT) BEGIN DECLARE a,b INT; DECLARE cur_1 CURSOR FOR SELECT s1 FROM t; DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1; OPEN cur_1; REPEAT FETCH cur_1 INTO a; UNTIL b = 1 END REPEAT; CLOSE cur_1; SET return_val = a; END;// mysql> CALL p25(@return_val)// Query OK, 0 rows affected (0.00 sec) mysql> SELECT @return_val// +-------------+ | @return_val | +-------------+ |5 | +-------------+ 1 row in set (0.00 sec) 。行一后最的 表是这为因, 值数了得获数参 到看以可。果结的后用调程过是面上 return_val 5 t 。常正作工也理处错出,常正作工标游道知以可此由Copyright 2005, MySQL AB 页 第 37信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 注关的业事 MySQL 息信些这留保时载转请
  • 38. Cursor Characteristics 游标的特性 游标的 :要摘 READ ONLY 性属读只 NOT SCROLLABLE 取读序顺 ASENSITIVE 感敏 (是标游为因。新更行进其对能不,值取中标游从以可只你,中 5.0 MySQL 的版 在 READ ONLY :做样这以可你。的读只) FETCH cursor1 INTO variable1; UPDATE t1 SET column1 = value1 WHERE CURRENT OF cursor1; 就码代面下。退后或进前中集果结在能不,行一下取读一逐许允只,的动滚以可不是也标游 :的误错是 FETCH PRIOR cursor1 INTO variable1; FETCH ABSOLUTE 55 cursor1 INTO variable1; (是标游为因,务事 行执上表的作操行进标游开打已在许允不也时同 updates ASENSITIVE 感敏) 是的用使你果如。么什成变会果结道知不就那,务事 止阻不你果如为因。的 update InnoDB 不而 MyISAM 。样一不会也果结,话的擎引储存 是 Security 安全措施 要摘 Privileges (1) CREATE ROUTINE Privileges (2) EXECUTE Privileges (3) GRANT SHOW ROUTINE? Privileges (4) INVOKERS AND DEFINERS 在为因但。题问的关相全安和权特于关些一论讨要们我里这 MySQL ,全完有没并能功的施措全安 。论讨多过行进其对会不们我以所 2. Privileges CREATE ROUTINE GRANT CREATE ROUTINE ON database-name . * TO user(s) [WITH GRANT OPTION]; root 了以可就 用在现 ,数函和程过储存建创以可样一权特他其同仅不它, 是权特的绍介要里这在 CREATE ROUTINE 。权特 有还时同,权特种这有拥户用 。表和图视建创以可还 Root ALTER ROUTINE 2. Privileges EXECUTE GRANT EXECUTE ON p TO peter [WITH GRANT OPTION]; 。权特个这有拥认默者建创程过,权特的程过储存行执或用使以可否是你定决是权特的面上 3. Privileges SHOW ROUTINE? GRANT SHOW ROUTINE ON db6.* TO joey [WITH GRANT OPTION]; :了权特的图视制控有经已们我为因 ,容兼证保了为,上础基个这在以所。 GRANT SHOW VIEW 加添会能可后日 GRANT SHOW ROUTINE ,候时的书本写在,的准标合符太不是做样这。权特Copyright 2005, MySQL AB 页 第 38信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 39. MySQL 。能功个这现实没还 4. Privileges Invokers and Definers 特权调用者和定义者 CREATE PROCEDURE p26 () SQL SECURITY INVOKER SELECT COUNT(*) FROM t // CREATE PROCEDURE p27 () SQL SECURITY DEFINER SELECT COUNT(*) FROM t // GRANT INSERT ON db5.* TO peter; // 你。分部一的性特序程的到提面前们我是 。吧句子 下一试测们我在现 SQL SECURITY Security 么怎以可 看看们我,作工的新行进陆登 用使后然。 了给赋权入插将,户用 是 root peter peter peter 。有户用 有只,力权 的 表对有没 :意注,程过储存 用使 peter t select root 5. Privileges Invokers and Definers /* Logged on with current_user = peter */ 户帐用使 peter 陆登 mysql> CALL p26(); ERROR 1142 (42000): select command denied to user peter@localhost for table t mysql> CALL p27(); +----------+ | COUNT(*) | +----------+ | 1| +----------+ 1 row in set (0.00 sec) 。力权的 的表对有没 为因是那。败失会时 程过的施措密保用调有含用调试尝 当 peter p26 peter select 的 有 ,力权 有 是因原。功成能就时程过的施措密保义定有含用调 当是但 petre root select Peter root 。行执以可程过此因,力权Copyright 2005, MySQL AB 页 第 39信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL注关的业事 息信些这留保时载转请
  • 40. Functions 函数 Summary: 要摘 CREATE FUNCTION 制限的数函 Limitations of functions 。数函的到提有没面前是的讲要我面下。了素元的用使中程过储存在以可楚清很经已们我 CREATE FUNCTION 创建函数 CREATE FUNCTION factorial (n DECIMAL(3,0)) RETURNS DECIMAL(20,0) DETERMINISTIC BEGIN DECLARE factorial DECIMAL(20,0) DEFAULT 1; DECLARE counter DECIMAL(3,0); SET counter = n; factorial_loop: REPEAT SET factorial = factorial * counter; SET counter = counter - 1; UNTIL counter = 1 END REPEAT; RETURN factorial; END // 程过跟数函)用引子例为作是只里这, :源来码代( "Understanding SQLs stored procedures" 的定指数函回返句语 有须必后数函建创是就同不的上法语的出指要需一唯,似相很 RETURN 。值型类 ,员成的 Jim Melton 是他,作大的 自来子例个这 SQL standard committee 子例个这用使定决我。页 的书在例原。者作的 "Understanding SQLs stored procedures" 223 。性范规的它为因是 2. Examples INSERT INTO t VALUES (factorial(pi)) // SELECT s1, factorial (s1) FROM t // UPDATE t SET s1 = factorial(s1) WHERE factorial(s1) < 5 // 的好很能果如。的样一是来起看数函他其跟中句语 到放它把,数函的要需们我是就面上 SQL 访中数函在能不是就那,陷缺有也们它,过不。样一调小的中曲乐像就,的妙美是将数函,理处 。大强程过储存如不们它使这,表问 3. Limitations 限制 Illegal::明声法非 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 化转权特、述描据数、作操据数行进够能不你此因,能功的数函了弱削制限的表问访能不 。吧性特些这持支会后以许也,些这靠是要主作工的们我但。制控务事是或Copyright 2005, MySQL AB 页 第 40信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 注关的业事 MySQL 息信些这留保时载转请
  • 41. 4. Limitations :明声法合 BEGIN END DECLARE IF ITERATE LOOP REPEAT RETURN SET declared variable WHILE ,大强很能功个这上际实。们它用使中句语流制控在后然,量变置设是就部全的做能你数函用利 。远很还却的要想们人离是但 Metadata元数据 元数据 :要摘 SHOW CREATE PROCEDURE / SHOW CREATE FUNCTION SHOW PROCEDURE STATUS / SHOW FUNCTION STATUS SELECT from mysql.proc SELECT from information_schema 看查要果如们我。中库据数 在存保都也们它,了程过多很了建创经已们我里这到 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 | +-----------+----------+-------------------+ 1 row in set (0.00 sec) 同这。 行执是法方的息信据数元得获种一第 SHOW CREATE PROCEDURE SHOW CREATE TABLE 。了用够经已下况情分部大在但,值回返的定设时程过建创你回返不并它。样一句语 MySQL 似类他其及以 2. Show mysql> SHOW PROCEDURE STATUS LIKE p6// +------+------+-----------+----------------+ | Db | Name | Type | Definer | ... +------+------+-----------+----------------+ | db5 | p6 | PROCEDURE | root@localhost | ... +------+------+-----------+----------------+ 1 row in set (0.01 sec) 得获种二第 metadata 行执是法方的息信 SHOW PROCEDURE STATUS 多更回返以可法方种这。 。节细的息信Copyright 2005, MySQL AB 页 第41信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, 注关的业事 MySQL 息信些这留保时载转请
  • 42. 3. SELECT from mysql.proc SELECT * FROM mysql.proc WHERE name = p6// +------+------+-----------+---------------+ | db | name | type | specific_name | ... +------+------+-----------+---------------+ | db5 | p6 | PROCEDURE | p6 | ... +------+------+-----------+---------------+ 1 row in set (0.00 sec) 行执是法方种三第 SELECT 。息信的多最供提能它,句语 4. SELECT from information_schema: 我最喜欢的方式。 我最喜欢的方式。 准标 用使向倾别特我。 是法方种四第 "SELECT ... FROM information_schema. ..." "ANSI/ISO " 同不有然当。误错现出会能可式方他其为因,式方现实好种是这信相我。作工成完去式方的 MySQL。由理些这看看的度态疑怀持的真认,由理同不有也,点观的同不持坚会户用 。式方 有 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 mysql> SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS -> WHERE TABLE_NAME = ROUTINES;// +------------+--------------------+---------------+ | TABLE_NAME | COLUMN_NAME | COLUMN_TYPE | +------------+--------------------+---------------+ | ROUTINES | SPECIFIC_NAME | varchar(64) | | ROUTINES | ROUTINE_CATALOG | longtext | | ROUTINES | ROUTINE_SCHEMA | varchar(64) | | ROUTINES | ROUTINE_NAME | varchar(64) | | ROUTINES | ROUTINE_TYPE | varchar(9) | | ROUTINES | DTD_IDENTIFIER | varchar(64) | | ROUTINES | ROUTINE_BODY | varchar(8) | | ROUTINES | ROUTINE_DEFINITION | longtext | | ROUTINES | EXTERNAL_NAME | varchar(64) | | ROUTINES | EXTERNAL_LANGUAGE | varchar(64) | | ROUTINES | PARAMETER_STYLE | varchar(8) | | ROUTINES | IS_DETERMINISTIC | varchar(3) | | ROUTINES | SQL_DATA_ACCESS | varchar(64) | | ROUTINES | SQL_PATH | varchar(64) | | ROUTINES | SECURITY_TYPE | varchar(7) | | ROUTINES | CREATED | varbinary(19) | | ROUTINES | LAST_ALTERED | varbinary(19) | | ROUTINES | SQL_MODE | longtext | | ROUTINES | ROUTINE_COMMENT | varchar(64) | | ROUTINES | DEFINER | varchar(77) | +------------+--------------------+---------------+ 20 rows in set (0.01 sec) 看查要想们我当?吧亮漂 information_schema 从们我,时图视 information_schema中 ,息信 selectCopyright 2005, MySQL AB 页 第 42信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 43. 在我是的到看们我里这。素元据数的据数元是的取获。样一取获 TABLES COLUMNS 和 从跟就 db6 。程过储存的义定中 库据数 mysql> SELECT COUNT(*) FROM INFORMATION_SCHEMA.ROUTINES -> WHERE ROUTINE_SCHEMA = db6;// +----------+ | COUNT(*) | +----------+ | 28 | +----------+ 1 row in set (0.02 sec) 式格新重们我, 程过的建创个一第们我看看步一进在现 p1 mysql。口窗出输端户客 | SPECIFIC_NAME | ROUTINE_CATALOG | ROUTINE_SCHEMA +---------------+-----------------+--------------- p19 | NULL | p19 | ROUTINE_NAME | ROUTINE_TYPE | DTD_IDENTIFIER +---------------+-----------------+--------------- | p19 | PROCEDURE | NULL | ROUTINE_BODY | ROUTINE_DEFINITION | EXTERNAL_NAME +--------------+--------------------+-------------- | SQL | select * from t | NULL | EXTERNAL_LANGUAGE | PARAMETER_STYLE | IS_DETERMINISTIC |-------------------+-----------------+----------------- | NULL | SQL | NO | SQL_DATA_ACCESS | SQL_PATH | SECURITY_TYPE | CREATED +-----------------+----------+---------------+-------- | CONTAINS SQL | NULL | DEFINER | 2004-12-19 | CREATED | LAST_ALTERED | SQL_MODE +---------------------+---------------------+--------- | 2004-12-19 15:00:26 | 2004-12-19 15:00:26 | | ROUTINE_COMMENT | DEFINER +-----------------+--------------- | | root@localhost Access control for the ROUTINE_DEFINITION column ROUTINE_DEFINITION列的访问控制 列的访问控制 的中 INFORMATION_SCHEMA 在 ROUTINE_DEFINITION 。的得获体程过成组数函或程过由是列 。见可者建创程过对只此因,息信感敏有会能可里这 CURRENT_USER <> INFORMATION_SCHEMA.ROUTINES.DEFINER SELECT 用使它对果如: 么那,户用的它建创是不户用的 mysql NULL 回返将 是不而,值 ROUTINE_DEFINITION 个这。列 。现实没还时书此作在能功查检 Additional clause in SHOW PROCEDURE STATUS显示过程状态子句 显示过程状态子句 SHOW PROCEDURE STATUS中的辅助子句 中的辅助子句 出列经已我然既 INFORMATION_SCHEMA.ROUTINES 释解去回以可就,列的中 SHOW PROCEDURE STATUS :是法语,节细新的 SHOW PROCEDURE STATUS [WHERE condition]; 和断判件条的中句语 SELECT 要需个有里这但。行回返中出输在则,真为果如:样一的句语Copyright 2005, MySQL AB 页 第43信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 44. 在:分部的意注别特 WHERE 用使须必你中句子 INFORMATION_SCHEMA ,字名的列 是的示显果结 :如例。字名的段字 SHOW PROCEDURE STATUS mysql> SHOW PROCEDURE STATUS WHERE Db = p; ERROR 1054 (42S22): Unknown column Db in where clause mysql> SHOW PROCEDURE STATUS WHERE ROUTINE_NAME = p; +------+------+-----------+----------------+ | Db | Name | Type | Definer | ... +------+------+-----------+----------------+ | db11 | p | PROCEDURE | root@localhost | ... +------+------+-----------+----------------+ 1 row in set (0.00 sec) 在能就许也们我,点这了道知 MySQL 。到用会不来从中际实是但,分高得获中试考证认 Details 细节 :要摘的页几面后 ALTER and DROP Oracle / SQL Server / DB2 / ANSI comparison Style Bugs Feature Requests Resources 为因,系关没这,习学去度程的意注到受该应们它据根会不但,节细多很了绍介们我中节环的后最 。些这现发会你中错试在 ALTER and DROP ALTER PROCEDURE p6 COMMENT Unfinished // DROP PROCEDURE p6 // Oracle Comparison 与Oracle的比较 的比较 Summary: 要摘 - Oracle 。明声再后开打在许允 MySQL 。明声候时的始开在须必 Oracle 。明声的样这 "CURSOR cursorname IS" 许允 MySQL 。明声 用使须必 "DECLARE cursorname CURSOR" Oracle () 。 要需制强不 MySQL () 。 有须必 Oracle 。素元表问访中数函在许允 MySQL 。素元表问访中数函在许允不 Oracle "packages" 。 持支 MySQL "packages" 。 持支不 同不多很有程过储存的 和 现发会你,话的程过储存 Oracle PL/SQL 的 过用使你果如 Oracle MySQL 的出指才刚我。)哈哈,别区是就这许也,大强程过储存的 PL/SQL 比能功的 MySQL :语者译( 。别区的见常些一是只 成换转程过储存 将供提家一是这,料资的多更读阅站网 http://www.ispirer.com 去以可也你 Oracle 。过用有没我为因 ,思意的好很品产的司公家这说有没并我。家厂的品产的程过储存 MySQL 。序程的来上 到移迁程过储存的 他其将出做人有对经已趣兴感是只我 DBMS MySQLCopyright 2005, MySQL AB 页 第 44信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL注关的业事 息信些这留保时载转请
  • 45. 巧技的移迁据数 巧技的移迁据数 巧技的移迁据数 巧技的移迁据数 Tips for migration.. 。 成改句语值赋的似类 把 "a:=b" "SET a=b" 为改句语 的中程过将 RETURN 的里这, "LEAVE label_at_start" 初最你是 label_at_start :如。记标的定设程过储存为 [ Oracle 中程过储存 在 ] CREATE PROCEDURE ... RETURN; ... [ MySQL 中程过储存 ]在 CREATE PROCEDURE () label_at_start: BEGIN ... LEAVE label_at_start; END 为因,要需中程过在仅仅骤步一这 MySQL 持支数函 RETURN 。 较比行平 较比行平 较比行平 较比行平 Side-By-Side Oracle MySQL CREATE PROCEDURE CREATE PROCEDURE sp_name sp_name AS BEGIN variable1 INTEGER DECLARE variable1 INTEGER; variable1 := 55 SET variable1 = 55; END END 与SQL Server的对比 的对比 :要摘 SQL Server 。头开 以须必字名数参 @ MySQL 。符识标规常是名数参 。 SQL Server :如,明声个多行进时同以可 "DECLARE v1 [data type], v2 [data type]" 。 MySQL :如,个一明声次每许允只 "DECLARE v1 [data type]; DECLARE v2 [data type]" SQL Server 。 有没中体程过储存 BEGIN ... END MySQL BEGIN ... END。句语 有须必 SQL Server ; 。句语束结号 以要需不 MySQL 。外句语条一后最了除,志标束结句语为作号 用使须必 ; SQL Server ,断判 和置设 "SET NOCOUNT"行进以可"IF @@ROWCOUNT" MySQL 。断判行进 用使以可但,些这有没 FOUND_ROWS() SQL Server 。句语 "WHILE ... BEGIN" 用使中 MySQL "WHILE ... DO" 。句语 用使 SQL Server 。派指行进 "SELECT" 用使许允 MySQL SET 。派指行进 许允只 SQL Server 。表问访中数函在许允 MySQL 表问访中数函在许允不 是会将序程 成换转序程的 或 Microsoft SQL Server 讲以所,多别特别区的 Microsoft Sybase MySQL 。巧技的别特多更要需换转以所,的上义定法语在是都别区且而,程过的长冗个 Some migration tips ... 巧技移迁些一 巧技移迁些一 巧技移迁些一 巧技移迁些一 ,量变程过表代不并中 在 为因,换转其将须必你,量变的 为名有中 SQL Server @xxx 果如 @ MySQLCopyright 2005, MySQL AB 页 第 45信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL注关的业事 息信些这留保时载转请
  • 46. 能可中表个某的库据数在为因。确明不义含其使会样那, 成改仅仅要不,量变局全是而 xxx 。 成改 将如,符字义定自的你成改缀前 把好最以所, 叫名列的列一有 xxx @ @xxx var_xxx 3. Side by Side 比对行平 比对行平 比对行平 比对行平 SQL Server MySQL CREATE PROCEDURE CREATE PROCEDURE sp_procedure1 sp_procedure1 AS () DECLARE @x VARCHAR(100) BEGIN EXECUTE sp_procedure2 @x DECLARE v__x VARCHAR(100); DECLARE c CURSOR FOR CALL sp_procedure2(v__x); DECLARE c CURSOR FOR SELECT * FROM t; SELECT * FROM t END END 与DB2的对比 的 DB2 PATH 。句语)径路( 许允 MySQL PATH 。句语)径路( 许允不 DB2 SIGNAL 。句语)令信( 许允 MySQL SIGNAL 。句语)令信( 许允不 DB2 。载重的名程例许允 MySQL 。载重的名程例对许允不 。法语 DB2 "label_x: ... GOTO label_x" 有 MySQL 。法语 的式正非有 "label label_x; ... GOTO label_x" DB2 。表问访数函许允 MySQL 。表问访数函许允不 有还,句语些一的 进引有没还 DB2 于在同不的一唯,致一 MySQL 和本基程过储存 MySQL DB2 定决来型类回返或数参的程例过通,程例的样一字名个两有以可 此因,载重许允 是就 DB2 DB2 。容兼的 DB2 与下向以可程过储存 以所,个哪行执 MySQL Some migration tips ... 巧技移迁些一 巧技移迁些一 巧技移迁些一 巧技移迁些一 作工时临论讨方地他其在会们我,句语 少缺 。巧技何任要需不本基移迁的里这 MySQL SIGNAL 定确( 。了以可就替代 的 用接直们我,句语 的 对而。题问的区 DB2 GOTO MySQL GOTO PATH 问访数函于关。了免避以可就缀前上加前名程例在要需只题问)录目库据数的程例找寻 DBMS 。了行就替代来程过储存的数参 用家大议建我,题问的表 OUT Side by Side 比对行平 比对行平 比对行平 比对行平 DB2 MySQL CREATE PROCEDURE CREATE PROCEDURE sp_name sp_name (parameter1 INTEGER) (parameter1 INTEGER) LANGUAGE SQL LANGUAGE SQL BEGIN BEGIN DECLARE v INTEGER; DECLARE v INTEGER; IF parameter1 >=5 THEN IF parameter1 >=5 THEN CALL p26(); CALL p26(); SET v = 2; SET v = 2; END IF; END IF; INSERT INTO t VALUES (v); INSERT INTO t VALUES (v); END @ END //Copyright 2005, MySQL AB 页 第 46信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 47. Standard Comparison 与SQL标准的比较 标准的比较 :要摘 Standard SQL requires: 求要的 准标 SQL [ DB2 ] 样一的中 跟 MySQL :性特 准标个两下以持支是标目的SQL )”式模储存“ 性特 ( Feature P001 "Stored Modules" P001 )”性整完算计“ 性特 ( Feature P002 "Computational completeness" P002 别区的 和 DB2 此因。程过储存的中 准标持支都者两是因原的似相 MySQL 和 SQL MySQL DB2 。准标更 或 比们我是但。样那法语准标 ANSI/ISO 离背们我像就 Oracle SQL ServerCopyright 2005, MySQL AB 页 第47信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 注关的业事 MySQL 息信些这留保时载转请
  • 48. Style 编程风格 CREATE PROCEDURE p () BEGIN /* Use comments! */ UPDATE t SET s1 = 5; CREATE TRIGGER t2_ai ... END;// ,中定约名命在。写大要字键关。程过储存个这写来格风程编种一了用使们我,中子例个这在 可们我, 为作上际实 。的么什” “为名列,的么什” “为好最名表中册手在为认我 t s DBA 。) 自来( "SQL Naming Conventions"章文考参以http://dbazine.com/gulutzan5.shtml C :样一的中言语 和释注 BEGIN 。)符字 个一是般一(进缩后 TAB 在 :样这面下欢喜更我。节细个这欢喜不我上实事, 平齐句语的前 END )END 与句语 使(缩回前 在 BEGIN CREATE PROCEDURE p () BEGIN /* Use comments! */ UPDATE t SET s1 = 5; CREATE TRIGGER t2_ai ... END;// <-- 有都家大望希是而,格风的我随跟都家大要是不并我里这在。前之是不而,缩回后 在当是就 END 。护维和读阅好更码代的你使会这。去下持坚中程过储存写编在能后然,格风的己自 :习学考参为作以可家大,子例的程过和数函些一是面下 Stored Procedure Example: tables_concat() 字符串连接的函数 和以可,数函的串符字一单个一到接连名表有所把是这 MySQL 的建内 。下一比对数函 group_concat() CREATE PROCEDURE tables_concat (OUT parameter1 VARCHAR(1000)) BEGIN DECLARE variable2 CHAR(100); DECLARE c CURSOR FOR SELECT table_name FROM information_schema.tables; DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END; /* 1 */ SET sql_mode=ansi; /* 2 */ SET parameter1 = ; OPEN c; LOOP FETCH c INTO variable2; /* 3 */ SET parameter1 = parameter1 || variable2 || .; END LOOP; CLOSE c; END; /* 1 */: 。句语 的中 他其像就,用作何任有没句语 "BEGIN END" 的里这 DBMS NULL /* 2 */: 。 为仍 后程过储存出退在,接连常正能 便以 为置设 sql_mode ansi "||" 将 sql_mode ansi /* 3 */: 。时行回返有没 当,理处错出 明声:法方的 环循出跳种一另 LOOP EXIT FETCHCopyright 2005, MySQL AB 页 第 48信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 49. :果结的程过个这用调们我是就下以 mysql> CALL tables_concat(@x); Query OK, 0 rows affected (0.05 sec) mysql> SELECT @x; +----------------------------------------------------+ | SCHEMATA.TABLES.COLUMNS.CHARACTER_SETS.COLLATIONS.C OLLATION_CHARACTER_SET_APPLICABILITY.ROUTINES.STATIST ICS.VIEWS.USER_PRIVILEGES.SCHEMA_PRIVILEGES.TABLE_PRI VILEGES.COLUMN_PRIVILEGES.TABLE_CONSTRAINTS.KEY_COLUM N_USAGE.TABLE_NAMES.columns_priv.db.fn.func.help_cate gory.help_keyword.help_relation.help_topic.host.proc. tables_priv.time_zone.time_zone_leap_second.time_zone 1 row in set (0.00 sec) 他其似类,集果结的量数的行含包型整得获是的目的程过面下 的中 DBMS 们我。 ROWNUM() 为名命就,果结的后 用调次每在存保来量变户用个一要需 rno() 。吧 @rno CREATE FUNCTION rno () RETURNS INT BEGIN SET @rno = @rno + 1; RETURN @rno; END; 过通 rno()的法方 SELECT :果结的序程用调是面下。数行了得获们我 mysql> SET @rno = 0;// Query OK, 0 rows affected (0.00 sec) mysql> SELECT rno(),s1,s2 FROM t;// +-------+------+------+ | rno() | s1 | s2 | +-------+------+------+ | 1| 1|a | | 2| 2|b | | 3| 3|c | | 4| 4|d | | 5| 5|e | +-------+------+------+ 5 rows in set (0.00 sec) 将中 在 SELECT @rno 了用使是巧技的零置 WHERE 的后今在性特个这而,能功值求的 中 MySQL 。失丢能可 CREATE FUNCTION rno_reset () RETURNS INTEGER BEGIN SET @rno = 0; RETURN 1; END; SELECT rno(),s1,s2 FROM t WHERE rno_reset()=1;//Copyright 2005, MySQL AB 页 第49信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, 注关的业事 MySQL 息信些这留保时载转请
  • 50. Function Example: running_total() 在立建数函的加累个这 。中数参到值传中时用调次每在要们我于在同不。上础基 rno() CREATE FUNCTION running_total (IN adder INT) RETURNS INT BEGIN SET @running_total = @running_total + adder; RETURN @running_total; END; :果结的后数函用调是面下 mysql> SET @running_total = 0;// Query OK, 0 rows affected (0.01 sec) mysql> SELECT s1,running_total(s1),s2 FROM t ORDER BY s1;// +------+-------------------+------+ | s1 | running_total(s1) | s2 | +------+-------------------+------+ | 1| 1|a | | 2| 3|b | | 3| 6|c | | 4| 10 | d | | 5| 15 | e | +------+-------------------+------+ 5 rows in set (0.01 sec) running_total()在数函 ORDER BY 。植移被能不也准标不既写样这但,用调后成完 Procedure Example: MyISAM "Foreign Key" insertion( MyISAM外键插入) ( 外键插入) 外键插入 MyISAM :例下如。查检行进擎引程过储存入加辑逻个这将以可你是但,键外持支不擎引储存 CREATE PROCEDURE fk_insert (p_fk INT, p_animal VARCHAR(10)) BEGIN DECLARE v INT; BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND SET v = 0; IF p_fk IS NOT NULL THEN SELECT 1 INTO v FROM tpk WHERE cpk = p_fk LIMIT 1; INSERT INTO tfk VALUES (p_fk, p_animal); ELSE SET v = 1; END IF; END; IF v <> 1 THEN DROP TABLE `The insertion failed`; END IF; END;Copyright 2005, MySQL AB 页 第 50信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 51. :意注 :意注 :意注 :意注 会 则,假为件条些这果如, 成变 致导会都件条 SQLEXCEPTION NOT FOUND v 或 0 v 为因, 成变 1 SELECT v :果结行运看看面下。行运有没 1 EXIT HANDLER 而, 值赋 给会 mysql> CREATE TABLE tpk (cpk INT PRIMARY KEY);// Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE tfk (cfk INT, canimal VARCHAR(10));// Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO tpk VALUES (1),(7),(10);// Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> CALL fk_insert(1,wombat);// Query OK, 1 row affected (0.02 sec) mysql> CALL fk_insert(NULL,wallaby);// Query OK, 0 rows affected (0.00 sec) mysql> CALL fk_insert(17,wendigo);// ERROR 1051 (42S02): Unknown table The insertion failed Procedure Example: Error Propagation 错误传递 常异有没果如。 程过到递传会就误错的中 程过, 程过了用调 程过, 程过用调 程过果如想设 1 2 2 3 3 1 了到递传常异终最,错出 程过致导后最,错出 程过致导,递传会就常异那,常异获捕器理处 2 1 ,生发制强常异使来句语 MySQL 在存中 准标得使性特种这。 例实端户客 ) (者用调 SQL SIGNAL 的性特此持支到直, DBMS 持支不还 。) (施措似类有也中 他其 RAISEERROR MySQL SIGNAL 。式方理处常异的面下用以可也家大。了理处行进来 用以可就家大,出推本版新 SIGNAL CREATE PROCEDURE procedure1 () BEGIN CALL procedure2(); SET @x = 1; END; CREATE PROCEDURE procedure2 () BEGIN CALL procedure3(); SET @x = 2; END; CREATE PROCEDURE procedure3 () BEGIN DROP TABLE error.`error #7815`; SET @x = 3; END; :下如果结后 程过用调 1 mysql> CALL procedure1()// ERROR 1051 (42S02): Unknown table error #7815 供可些一生产以可 用使而,行运功成句语 @x 条一有没为因,变改有没并 "SET @x = ..." DROP 。在存表的 做叫字名有没祷祈好最们我里这在,过不。息信误错的断诊 `error`Copyright 2005, MySQL AB 页 第 51信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 52. Procedure Example: Library 库 :置设样这们我以所,程过用调能都户用的限权有拥望希们我。明说格规的细详有用应的库对 GRANT ALL ON database-name.* TO user-name; 义定要需只,题问有没,限权的程过用使问访有只户用他其要果如 SQL SECURITY DEFINER 。来出明声的式显好最但,的认默是项选个这而,了以可就性特 子例。空为否是名书,定确否是 的书试测须必里这,程过的本书加添中库据数向个一是面下 id MySQL 。代替的能功制限 CHECK 的持支不 对是 CREATE PROCEDURE add_book (p_book_id INT, p_book_title VARCHAR(100)) SQL SECURITY DEFINER BEGIN IF p_book_id < 0 OR p_book_title= THEN SELECT Warning: Bad parameters; END IF; INSERT INTO books VALUES (p_book_id, p_book_title); END; 。告警出给则有如,主买的个一过超有否是查检须必程过,程过的主买加添个一要需们我 :下如,成完中询查子个一在以可能功个这 IF (SELECT COUNT(*) FROM table-name) > 2) THEN ... END IF; 用们我是于,洞漏有能功询查子时书此作写在,过不 "SELECT COUNT(*) INTO variable-name" 。替代 CREATE PROCEDURE add_patron (p_patron_id INT, p_patron_name VARCHAR(100)) SQL SECURITY DEFINER BEGIN DECLARE v INT DEFAULT 0; SELECT COUNT(*) FROM patrons INTO v; IF v > 2 THEN SELECT warning: already there are ,v,patrons!; END IF; INSERT INTO patrons VALUES (p_patron_id,p_patron_name); END; 及以,主买的书本有拥经已示显望希们我中程过理处务事在。程过的帐付本书要需们我面下 的同不种两用使会们我,得获来 的 标游对过通以可息信些这,书的有拥主买些这 CURSOR Fetch 通是种二第, 是否是后作动 在量变查检是种一第,毕完经已据数 否是试测来法方 fetch fetch NULL 看序程中块 的同不在标游个两果如。作动败失的 获捕理处误错 NOT FOUND fetch 过 BEGIN/END 覆域用作的们它使能才做样这,量变些这明声中 块 主在要们我但,洁整得显会来起 BEGIN/END 。程过个整盖 CREATE PROCEDURE checkout (p_patron_id INT, p_book_id INT) SQL SECURITY DEFINER BEGIN DECLARE v_patron_id, v_book_id INT; DECLARE no_more BOOLEAN default FALSE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more=TRUE; BEGIN DECLARE c1 CURSOR FOR SELECT patron_id FROM transactions WHERE book_id = p_book_id;Copyright 2005, MySQL AB 页 第 52信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 53. OPEN c1; SET v_patron_id=NULL; FETCH c1 INTO v_patron_id; IF v_patron_id IS NOT NULL THEN SELECT Book is already out to this patron:, v_patron_id; END IF; CLOSE c1; END; BEGIN DECLARE c2 CURSOR FOR SELECT book_id FROM transactions WHERE patron_id = p_patron_id; OPEN c2; book_loop: LOOP FETCH c2 INTO v_book_id; IF no_more THEN LEAVE book_loop; END IF; SELECT Patron already has this book:, v_book_id; END LOOP; END; INSERT INTO transactions VALUES (p_patron_id, p_book_id); END; Procedure Example: Hierarchy (I) 分层次 分层次 ,表 个一有拥们我。能功分部 hierarchy() 中 他其是的现实程过 DBMS CONNECT BY Persons 然。人个一第的表列递传 数参过通们我。连相先祖与列 person_id 过通代后的中表 start_with 么那了学家大信相,页两面后在码代)个两是际实(程过个这。代后和先祖示显序顺按后 。释注的性明说些一给会是还我始开过不,的上跟己自以可也点细仔得读阅,多 hierarchy() 临个了立建它是的要重过不,作动化始初像点有用作,数参入输为作字名的 受接程过 person 时此,程过 了用调它后然。据数的行果结的到找查储存来用,表时 hierarchy2() hierarchy2() 但,了要需不就步一这,子儿个 或 有只亲父果如。身自用调的停不,环循行进始开程过 1 0 节后最到直,询查环循的断不行进树对要此因,支分个每到询查要以所,此如会不上实事 处误错了用使后行执句语 条每在还里这们我。询查的支分个一另行进点支分回返才点 SQL 出开离后然,息信断诊出输 set a flag (error) 用使序程,败失句语果如, 理 "SELECT string" 。程过的错 以所,)块 置放中块 在是就(套嵌的句语合复了用使还里这在时同 BEGIN END BEGIN END 明声的中句语合复层外在住记过不。明声行进理处错出和量变的句语定特联关为以可才们我 就明声的层内,后毕完句语合复层内在是就有还,载重了用使你非除,效有仍中句语层内在 。效失 用调功成是的后之此在,的程过 hierarchy()是则页后,码代建创的程过 是页一下 hierarchy2() hierarchy() 。果结的程过Copyright 2005, MySQL AB 页 第 53信来请误错有如 chenpengyi_007@163.com 对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 54. CREATE PROCEDURE hierarchy (start_with CHAR(10)) proc: BEGIN DECLARE temporary_table_exists BOOLEAN; BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; DROP TABLE IF EXISTS Temporary_Table; END; BEGIN DECLARE v_person_id, v_father_id INT; DECLARE v_person_name CHAR(20); DECLARE done, error BOOLEAN DEFAULT FALSE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET error = TRUE; CREATE TEMPORARY TABLE Temporary_Table (person_id INT, person_name CHAR(20), father_id INT); IF error THEN SELECT CREATE TEMPORARY failed; LEAVE proc; END IF; SET temporary_table_exists=TRUE; SELECT person_id, person_name INTO v_person_id, v_person_name FROM Persons WHERE person_name = start_with limit 1; IF error THEN SELECT First SELECT failed; LEAVE proc; END IF; IF v_person_id IS NOT NULL THEN INSERT INTO Temporary_Table VALUES (v_person_id, v_person_name, v_father_id); IF error THEN SELECT First INSERT failed; LEAVE proc; END IF; CALL hierarchy2(v_person_id); IF error THEN SELECT First CALL hierarchy2() failed; END IF; END IF; SELECT person_id, person_name, father_id FROM Temporary_Table; IF error THEN SELECT Temporary SELECT failed; LEAVE proc; END IF; END; IF temporary_table_exists THEN DROP TEMPORARY TABLE Temporary_Table; END IF; END;Copyright 2005, MySQL AB 54页 第信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 注关的业事 MySQL 息信些这留保时载转请
  • 55. CREATE PROCEDURE hierarchy2 (start_with INT) proc: BEGIN DECLARE v_person_id INT, v_father_id INT; DECLARE v_person_name CHAR(20); DECLARE done, error BOOLEAN DEFAULT FALSE; DECLARE c CURSOR FOR SELECT person_id, person_name, father_id FROM Persons WHERE father_id = start_with; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET error = TRUE; OPEN c; IF error THEN SELECT OPEN failed; LEAVE proc; END IF; REPEAT SET v_person_id=NULL; FETCH c INTO v_person_id, v_person_name, v_father_id; IF error THEN SELECT FETCH failed; LEAVE proc; END IF; IF done=FALSE THEN INSERT INTO Temporary_Table VALUES (v_person_id, v_person_name, v_father_id); IF error THEN SELECT INSERT in hierarchy2() failed; END IF; CALL hierarchy2(v_person_id); IF error THEN SELECT Recursive CALL hierarchy2() failed; END IF; END IF; UNTIL done = TRUE END REPEAT; CLOSE c; IF error THEN SELECT CLOSE failed; END IF; END;Copyright 2005, MySQL AB 55页 第信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com 注关的业事 MySQL 息信些这留保时载转请
  • 56. 用调是面下 hierarchy() :果结的后 mysql> CREATE TABLE Persons (person_id INT, person_name CHAR(20), father_id INT);// Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO Persons VALUES (1,Grandpa,NULL);// Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO Persons VALUES (2,Pa-1,1),(3,Pa-2,1);// Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> INSERT INTO Persons VALUES (4,Grandson-1,2),(5,Grandson-2,2);// Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> call hierarchy(Grandpa)// +-----------+-------------+-----------+ | person_id | person_name | father_id | +-----------+-------------+-----------+ | 1 | Grandpa | NULL | | 2 | Pa-1 | 1| | 4 | Grandson-1 | 2| | 5 | Grandson-2 | 2| | 3 | Pa-2 | 1| +-----------+-------------+-----------+ 5 rows in set (0.01 sec) Query OK, 0 rows affected (0.01 sec) 许也。法算”先优度深“是的用使,询查始开点节子儿从又后然,子孙到查直一先祖从询查 果如想试,错出会许也话的深太环循。洞漏的到虑考没我些有会,杂复于过程过 hierarchy() 节的树中其是就,的到想能也家大过不,的译直是里这(时爷爷的己自是人有当则,代 有 100 通可也 明说了为是只里这在我过不。环循限无入进会就,)环个一成形,绕缠相互点 MySQL 。能功 现实环循的程过储存对过 CONNECT BY Tips when writing long routines 书写长例程时的技巧 行 个一建创在我是面下。用没能可多大息信误错的出输此因,器试调程过储存有没 MySQL 20 :法方的理处常异行进时程过的 和器辑编本文在能功 和 用使,口窗器辑编到贝拷句语将,器辑编本文开打 copy paste MySQL 。便方很换切间口窗 因,了多高率效码代序程看睛眼用光你比这。错排行进句一掉去次每以可,误错法语是果如 。错没都切一乎似候时的看为 行运示标来 、 、 是以可 ( 入加后句语的行执可条每在则,误错时行运是果如 "SELECT n;" n 0 1 2 。了断诊行进来流制控中追以可就你后用调,)句语条哪了到 加添过通以可则,误错据数是果如 "DECLARE CONTINUE HANDLER FOR ... BEGIN END;" 。行进续继以可们我使个这过跳此因,在存不据数的库据数时试测往往为因,过跳来Copyright 2005, MySQL AB 页 第 56信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 57. Bugs 漏洞或缺陷 ,)版 出已时译翻,测外是则 ,测内即思意版 中件软:语者译(版 是然仍 MySQL alpha alpha beta beta :下如洞漏的 和 的算计我,洞漏重严多许有仍中程过储存其 2004-10-27 2004-12-14 Bug Count On October 27 2004: 类种 Category Count Causes Operating System To Reboot 1 )启重统系致导( Crashes or Hangs 14 )起挂或溃崩致导( Returns Packets out of order 5 回返( Packets out of order) Fails 21 -- 41 Bug Count On December 14 2004: Category Count Causes Operating System To Reboot 1 Crashes or Hangs 23 Returns Packets out of order 6 Fails 31 -- 61 问访过通以可你 MySQL :骤步是面下,误错的器发触和程过储存询查来站网布发洞漏 1. 址网开打 http://bugs.mysql.com 2. 击点 "Advanced Search" 入输中框 3. 在 "Find bugs with any of the words" "procedure* trigger*". 择选活然,误错个 回返为认默中框拉下在 4. 10 "All" 5. 击点 "Boolean mode" 6. 击点是后最 "Search"Copyright 2005, MySQL AB 页 第 57信来请误错有如 chenpengyi_007@163.com对您谢感时同,读阅和持支的您谢谢, MySQL 注关的业事 息信些这留保时载转请
  • 58. Feature Requests 将会出现的特性 :要摘 SIGNAL PATH Accessing Tables in Functions or Triggers 表问访中器发触或数函在 BEGIN ATOMIC ... END Encrypted storage 储存密加 Timeout 时超 Debugger 器试调 External Languages 性特言语部外 DROP ... CASCADE|RESTRICT :能功的加添要需切急们我是面下 和 有拥是性特的要需最数函们我 DB2 ANSI/ISO 行运使能功时超要需还时同,能功大强的准标 。止停作动或环循的长过间时 Resources 您可以获得的资源 (I) MySQL 站网的 (II) MySQL 源资的载下供可 (III) 册手考参和程教 。方地和法方的息信多更得获者读诉告将我后最的书在 MySQL网站 网站 MySQL :节章程过储存册手考参 http://www.mysql.com/doc/en/Stored_Procedures.html “ MySQL :章文新最”程过储存 http://www.mysql.com/newsletter/2004-01/a0000000297.html MySQL :片灯幻的议会户用 mysql.mirror.anlx.net/Downloads/Presentations/MySQL-User-Conference-2003/MySQL -Stored-Procedures.pdf 。源资的取获站网从以可你是都些这 MySQL下载 下载 > cd ~/mysql-5.0/mysql-test/t > dir sp* 10025 2004-10-23 05:19 sp-error.test 3974 2004-10-23 05:19 sp-security.test 754 2004-08-07 08:51 sp-threads.test 45344 2004-10-24 06:09 sp.test > cd ~/mysql-5.0/Docs > dir sp* 41909 2004-08-05 09:19 sp-imp-spec.txt 4948 2004-08-05 09:19 sp-implemented.txt 载下以可你,息信的多更要需果如 MySQL 5.0 是而,身本码代读去者读让是不我然当。包码代源 在,本脚试测的里录目 读阅去 mysql-test Docs )程过作操有面上(。闻新和料资档文有里录目Copyright 2005, MySQL AB 页 第 58信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请
  • 59. Books 教程和参考手册 Understanding SQLs Stored Procedures: A Complete Guide to SQL/PSM )了译翻不,名书( 者作 Author: Jim Melton 行发 Publisher: Morgan Kaufmann Only available second-hand. ,书考参的程过储存 准标于关本一是这 SQL MySQL 为作此因,准标 合符量尽也 SQL MySQL 。考参为作本一有能好最您的户用 Conclusion结束语 结束语 结束 ,书本这欢喜您果如。的部全住记以可家大信相,了念概么什些述复去再不就我后最了到 于关是会将书本一下,籍书列系 多更到找站网的们我在以可你 "MySQL 5.0 New Features" 。”图视“和”器发触“ 。 :坛论 来迎欢论评么什有书本这对您果如,注关的您谢感 MySQL http://forums.mysql.com/ About MySQL (这部分就不翻译了,估计大家也不看,呵呵) 这部分就不翻译了,估计大家也不看,呵呵) MySQL AB develops and supports a family of high performance, affordable database servers and tools. The companys flagship product is MySQL, the worlds most popular open source database, with more than six million active installations. Many of the worlds largest organizations, including Yahoo!, Sabre Holdings, The Associated Press, Suzuki and NASA are realizing significant cost savings by using MySQL to power high-volume Web sites, business-critical enterprise applications and packaged software. With headquarters in Sweden and the United States ¨C and operations around the world ¨C MySQL AB supports both open source values and corporate customers needs in a profitable, sustainable business. For more information about MySQL, please visit www.mysql.com. 对是的目,译翻来书的门入较比本这了选挑以所,试尝的样这做次一第是这:话的者译 是但,误错的面里谅原以可家大望希,误错的少不有会能可面里,持支的户用 MySQL 内国 留保请时载转,持支位各谢谢。作操的家大响影会不对绝,的上法文是会只误错,证保我 以,册一第的列系》性特新 《——作大生先 是这。明声和息信者作 Peter Gulutzan MySQL 5.0 间时果如,信写我给以可也料资么什要需果如家大然当,料资他其的列系此译翻空抽会我后 。见意贵宝和读阅的家大谢谢,励鼓和持支位各到得望希,译翻复回您给会我足充 奕朋陈:者作 学大技科子电安西:校院业毕 , 、 , :好爱 Java JSP Oracle PL/SQL MySQL :箱邮 chenpengyi_007@163.com )……了走就快很能可( # 学大技科子电安西:址地 96 113Copyright 2005, MySQL AB 页 第 59信来请误错有如 对您谢感时同,读阅和持支的您谢谢, chenpengyi_007@163.com MySQL 注关的业事 息信些这留保时载转请