马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
对于IT经理来说,令他们喜欢的MySQL的简单性还有另一方面。MySQL可以运行的更快速。某些人或许会说MySQL缺少了一些人们想要的功能。<pstyle="TEXT-INDENT:2em">WhyMySQLStatementsareLegalinaProcedureBody<pstyle="TEXT-INDENT:2em">甚么MySQL语句在存储历程体中是正当的?<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">甚么样的SQL语句在Mysql存储过程当中才是正当的呢?你能够创立一个包括INSERT,UPDATE,DELETE,SELECT,DROP,CREATE,REPLACE等的语句。你独一必要记着的是假如代码中包括MySQL扩大功效,那末代码将不克不及移植。在尺度SQL语句中:任何数据库界说言语都是正当的,如:<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp()DELETEFROMt;//<pstyle="TEXT-INDENT:2em">SET、COMMIT和ROLLBACK也是正当的,如:<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp()SET@x=5;//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">MySQL的附加功效:任何数据操纵言语的语句都将正当。<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp()DROPTABLEt;//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">MySQL扩大功效:间接的SELECT也是正当的:<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp()SELECTa;//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">特地提一下,我将存储过程当中包含DDL语句的功效称为MySQL附加功效的缘故原由是在SQL尺度中把这个界说为非中心的,便可选组件。<pstyle="TEXT-INDENT:2em">在历程体中有一个束缚,就是不克不及有对例程或表操纵的数据库操纵语句。比方上面的例子就长短法的:<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp1()<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp2()DELETEFROMt;//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">上面这些对MySQL5.0来讲全新的语句,历程体中长短法的:<pstyle="TEXT-INDENT:2em">CREATEPROCEDURE,ALTERPROCEDURE,DROPPROCEDURE,CREATEFUNCTION,<pstyle="TEXT-INDENT:2em">DROPFUNCTION,CREATETRIGGER,DROPTRIGGER.<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">不外你可使用<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREdb5.p1()DROPDATABASEdb5//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">可是相似<pstyle="TEXT-INDENT:2em">"USEdatabase"<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">语句也长短法的,由于MySQL假定默许数据库就是历程的事情场合。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">CalltheProcedure挪用存储历程<pstyle="TEXT-INDENT:2em">1.<pstyle="TEXT-INDENT:2em">如今我们就能够挪用一个存储历程了,你所必要输出的全体就是CALL和你历程名和一个括号再一次夸大,括号是必需确当你挪用例子内里的p1历程时,了局是屏幕前往了t表的内容<pstyle="TEXT-INDENT:2em">mysql>CALLp1()//<pstyle="TEXT-INDENT:2em">+------+<pstyle="TEXT-INDENT:2em">|s1|<pstyle="TEXT-INDENT:2em">+------+<pstyle="TEXT-INDENT:2em">|5|<pstyle="TEXT-INDENT:2em">+------+<pstyle="TEXT-INDENT:2em">1rowinset(0.03sec)<pstyle="TEXT-INDENT:2em">QueryOK,0rowsaffected(0.03sec)<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">由于过程当中的语句是"SELECT*FROMt;"
<pstyle="TEXT-INDENT:2em">2.Letmesaythatagain,anotherway.<pstyle="TEXT-INDENT:2em">其他完成体例<pstyle="TEXT-INDENT:2em">mysql>CALLp1()//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">和上面语句的实行效果一样:<pstyle="TEXT-INDENT:2em">mysql>SELECT*FROMt;//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">以是,你挪用p1历程就相称于你实行了上面语句:<pstyle="TEXT-INDENT:2em">"SELECT*FROMt;"<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">好了,次要的常识点"创立和挪用历程办法"已分明了。我但愿你能对本人说这相称复杂。可是很快我们就有一系列的实习,每次都加一便条句,大概改动已存在的子句。那样在写庞大部件前我们将会有良多可用的子句。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">CharacteristicsClauses特性子句<pstyle="TEXT-INDENT:2em">1.<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp2()<pstyle="TEXT-INDENT:2em">LANGUAGESQL<--<pstyle="TEXT-INDENT:2em">NOTDETERMINISTIC<--<pstyle="TEXT-INDENT:2em">SQLSECURITYDEFINER<--<pstyle="TEXT-INDENT:2em">COMMENTAProcedure<--<pstyle="TEXT-INDENT:2em">SELECTCURRENT_DATE,RAND()FROMt//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">这里我给出的是一些能反应存储历程特征的子句。子句内容在括号以后,主体之前。这些子句都是可选的,他们有甚么感化呢?<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">2.<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp2()<pstyle="TEXT-INDENT:2em">LANGUAGESQL<--<pstyle="TEXT-INDENT:2em">NOTDETERMINISTIC<pstyle="TEXT-INDENT:2em">SQLSECURITYDEFINER<pstyle="TEXT-INDENT:2em">COMMENTAProcedure<pstyle="TEXT-INDENT:2em">SELECTCURRENT_DATE,RAND()FROMt//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">很好,这个LANGUAGESQL子句是没有感化的。仅是为了申明上面历程的主体利用SQL言语编写。这条是体系默许的,但你在这里声明是有效的,由于某些DBMS(IBM的DB2)必要它,假如你存眷DB2的兼容成绩最好仍是用上。别的,从此大概会呈现除SQL外的其他言语撑持的存储历程。<pstyle="TEXT-INDENT:2em">3.<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp2()<pstyle="TEXT-INDENT:2em">LANGUAGESQL<pstyle="TEXT-INDENT:2em">NOTDETERMINISTIC<--<pstyle="TEXT-INDENT:2em">SQLSECURITYDEFINER<pstyle="TEXT-INDENT:2em">COMMENTAProcedure<pstyle="TEXT-INDENT:2em">SELECTCURRENT_DATE,RAND()FROMt//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">下一个子句,NOTDETERMINISTIC,是传送给体系的信息。这里一个断定历程的界说就是那些每次输出一样输入也一样的程序。在这个案例中,既然主体中含有SELECT语句,那前往一定是未知的因而我们称其NOTDETERMINISTIC。可是MySQL内置的优化程序不会注重这个,最少在如今不注重。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">4.<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp2()<pstyle="TEXT-INDENT:2em">LANGUAGESQL<pstyle="TEXT-INDENT:2em">NOTDETERMINISTIC<pstyle="TEXT-INDENT:2em">SQLSECURITYDEFINER<--<pstyle="TEXT-INDENT:2em">COMMENTAProcedure<pstyle="TEXT-INDENT:2em">SELECTCURRENT_DATE,RAND()FROMt//<pstyle="TEXT-INDENT:2em">下一个子句是SQLSECURITY,能够界说为SQLSECURITYDEFINER或SQLSECURITYINVOKER。<pstyle="TEXT-INDENT:2em">这就进进了权限把持的范畴了,固然我们在前面将会有测试权限的例子。<pstyle="TEXT-INDENT:2em">SQLSECURITYDEFINER<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">意味着在挪用时反省创立历程用户的权限(另外一个选项是SQLSECURITYINVOKER)。<pstyle="TEXT-INDENT:2em">如今而言,利用<pstyle="TEXT-INDENT:2em">SQLSECURITYDEFINER<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">指令告知MySQL服务器反省创立历程的用户就能够了,当历程已被挪用,就不反省实行挪用历程的用户了。而另外一个选项(INVOKER)则是告知服务器在这一步仍旧要反省挪用者的权限。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">5.<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp2()<pstyle="TEXT-INDENT:2em">LANGUAGESQL<pstyle="TEXT-INDENT:2em">NOTDETERMINISTIC<pstyle="TEXT-INDENT:2em">SQLSECURITYDEFINER<pstyle="TEXT-INDENT:2em">COMMENTAProcedure<--<pstyle="TEXT-INDENT:2em">SELECTCURRENT_DATE,RAND()FROMt//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">COMMENTAprocedure是一个可选的正文申明。
<pstyle="TEXT-INDENT:2em">最初,正文子句会跟历程界说存储在一同。这个没有流动的尺度,我在文中会指出没有流动尺度的语句,不外侥幸的是这些在我们尺度的SQL中很少。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">6.<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp2()<pstyle="TEXT-INDENT:2em">LANGUAGESQL<pstyle="TEXT-INDENT:2em">NOTDETERMINISTIC<pstyle="TEXT-INDENT:2em">SQLSECURITYDEFINER<pstyle="TEXT-INDENT:2em">COMMENT<pstyle="TEXT-INDENT:2em">SELECTCURRENT_DATE,RAND()FROMt//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">下面历程跟上面语句是等效的:<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp2()<pstyle="TEXT-INDENT:2em">SELECTCURRENT_DATE,RAND()FROMt//<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">特性子句也有默许值,假如省略了就相称于:<pstyle="TEXT-INDENT:2em">LANGUAGESQLNOTDETERMINISTICSQLSECURITYDEFINERCOMMENT<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">Digressions一些题外话<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">Digression:<pstyle="TEXT-INDENT:2em">挪用p2()//的了局<pstyle="TEXT-INDENT:2em">mysql>callp2()//<pstyle="TEXT-INDENT:2em">+--------------+-----------------+<pstyle="TEXT-INDENT:2em">|CURRENT_DATE|RAND()|<pstyle="TEXT-INDENT:2em">+--------------+-----------------+<pstyle="TEXT-INDENT:2em">|2004-11-09|0.7822275075896|<pstyle="TEXT-INDENT:2em">+--------------+-----------------+<pstyle="TEXT-INDENT:2em">1rowinset(0.26sec)<pstyle="TEXT-INDENT:2em">QueryOK,0rowsaffected(0.26sec)<pstyle="TEXT-INDENT:2em">当挪用历程p2时,一个SELECT语句被实行前往我们希冀取得的随机数。<pstyle="TEXT-INDENT:2em">Digression:sql_modeunchanging<pstyle="TEXT-INDENT:2em">不会改动的<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">sql_mode<pstyle="TEXT-INDENT:2em">mysql>setsql_mode=ansi//<pstyle="TEXT-INDENT:2em">mysql>createprocedurep3()selecta||b//<pstyle="TEXT-INDENT:2em">mysql>setsql_mode=//<pstyle="TEXT-INDENT:2em">mysql>callp3()//<pstyle="TEXT-INDENT:2em">+------------+<pstyle="TEXT-INDENT:2em">|a||b|<pstyle="TEXT-INDENT:2em">+------------+<pstyle="TEXT-INDENT:2em">|ab|<pstyle="TEXT-INDENT:2em">+------------+<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">MySQL在历程创立时会主动坚持运转情况。比方:我们必要利用两条竖线来毗连字符串可是这只要在sqlmode为ansi的时分才正当。假如我们将sqlmode改成non-ansi,不必忧虑,它仍旧能事情,只需它第一次利用时能一般事情。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">Exercise实习<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">Question<pstyle="TEXT-INDENT:2em">成绩<pstyle="TEXT-INDENT:2em">假如你不介怀实习一下的话,试可否不看前面的谜底就可以处置这些哀求。<pstyle="TEXT-INDENT:2em">创立一个历程,显现`Helloworld`。用约莫5秒工夫往思索这个成绩,既然你已学到了这里,这个应当很复杂。当你思索成绩的时分,我们再随机选择一些方才讲过的器材温习:<pstyle="TEXT-INDENT:2em">DETERMINISTIC<pstyle="TEXT-INDENT:2em">(断定性)子句是反应输入和输出依附特征的子句…挪用历程利用CALL历程名(参数列表)体例。好了,我猜工夫也到了。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">Answer<pstyle="TEXT-INDENT:2em">谜底<pstyle="TEXT-INDENT:2em">好的,谜底就是在历程体中包括<pstyle="TEXT-INDENT:2em">"SELECTHello,world"<pstyle="TEXT-INDENT:2em">语句<pstyle="TEXT-INDENT:2em">MySQL<pstyle="TEXT-INDENT:2em">mysql>CREATEPROCEDUREp4()SELECTHello,world//<pstyle="TEXT-INDENT:2em">QueryOK,0rowsaffected(0.00sec)<pstyle="TEXT-INDENT:2em">mysql>CALLp4()//<pstyle="TEXT-INDENT:2em">+--------------+<pstyle="TEXT-INDENT:2em">|Hello,world|<pstyle="TEXT-INDENT:2em">+--------------+<pstyle="TEXT-INDENT:2em">|Hello,world|<pstyle="TEXT-INDENT:2em">+--------------+<pstyle="TEXT-INDENT:2em">1rowinset(0.00sec)QueryOK,0rowsaffected(0.00sec)
<pstyle="TEXT-INDENT:2em">Parameters参数<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">让我们更进一步的研讨怎样在存储过程当中界说参数<pstyle="TEXT-INDENT:2em">1.CREATEPROCEDUREp5<pstyle="TEXT-INDENT:2em">()...<pstyle="TEXT-INDENT:2em">2.CREATEPROCEDUREp5<pstyle="TEXT-INDENT:2em">([IN]namedata-type)...<pstyle="TEXT-INDENT:2em">3.CREATEPROCEDUREp5<pstyle="TEXT-INDENT:2em">(OUTnamedata-type)...<pstyle="TEXT-INDENT:2em">4.CREATEPROCEDUREp5<pstyle="TEXT-INDENT:2em">(INOUTnamedata-type)...<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">回想一下后面讲过的参数列表必需在存储历程名后的括号中。下面的第一个例子中的参数列表是空的,第二个例子中有一个输出参数。这里的词IN可选,由于默许参数为IN(input)。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">第三个例子中有一个输入参数,第四个例子中有一个参数,既能作为输出也能够作为输入。<pstyle="TEXT-INDENT:2em">INexample输出的例子<pstyle="TEXT-INDENT:2em">mysql>CREATEPROCEDUREp5(pINT)SET@x=p//<pstyle="TEXT-INDENT:2em">QueryOK,0rowsaffected(0.00sec)<pstyle="TEXT-INDENT:2em">mysql>CALLp5(12345)//<pstyle="TEXT-INDENT:2em">QueryOK,0rowsaffected(0.00sec)<pstyle="TEXT-INDENT:2em">mysql>SELECT@x//<pstyle="TEXT-INDENT:2em">+-------+<pstyle="TEXT-INDENT:2em">|@x|<pstyle="TEXT-INDENT:2em">+-------+<pstyle="TEXT-INDENT:2em">|12345|<pstyle="TEXT-INDENT:2em">+-------+<pstyle="TEXT-INDENT:2em">1rowinset(0.00sec)<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">这个IN的例子演示的是有输出参数的历程。在历程体中我将会话变量x设定为参数p的值。然后挪用历程,将12345传进参数p。选择显现会话变量@x,证实我们已将参数值12345传进。<pstyle="TEXT-INDENT:2em">OUTexample输入的例子<pstyle="TEXT-INDENT:2em">mysql>CREATEPROCEDUREp6(OUTpINT)<pstyle="TEXT-INDENT:2em">->SETp=-5//<pstyle="TEXT-INDENT:2em">mysql>CALLp6(@y)//<pstyle="TEXT-INDENT:2em">mysql>SELECT@y//<pstyle="TEXT-INDENT:2em">+------+<pstyle="TEXT-INDENT:2em">|@y|<pstyle="TEXT-INDENT:2em">+------+<pstyle="TEXT-INDENT:2em">|-5|<pstyle="TEXT-INDENT:2em">+------+<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">这是另外一个例子。此次的p是输入参数,然后在历程挪用中将p的值传进会话变量@y中。<pstyle="TEXT-INDENT:2em">在历程体中,我们给参数赋值-5,在挪用后我们能够看出,OUT是告知DBMS值是从过程当中传出的。<pstyle="TEXT-INDENT:2em">一样我们能够用语句<pstyle="TEXT-INDENT:2em">"SET@y=-5;"<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">来到达一样的效果<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">CompoundStatements复合语句<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">如今我们睁开的具体剖析一下历程体:<pstyle="TEXT-INDENT:2em">CREATEPROCEDUREp7()<pstyle="TEXT-INDENT:2em">BEGIN<pstyle="TEXT-INDENT:2em">SET@a=5;<pstyle="TEXT-INDENT:2em">SET@b=5;<pstyle="TEXT-INDENT:2em">INSERTINTOtVALUES(@a);<pstyle="TEXT-INDENT:2em">SELECTs1*@aFROMtWHEREs1>=@b;<pstyle="TEXT-INDENT:2em">END;///*IwontCALLthis.<pstyle="TEXT-INDENT:2em">这个语句将不会被挪用<pstyle="TEXT-INDENT:2em">*/<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">完成历程体的机关就是BEGIN/END块。这个BEGIN/END语句块和Pascal言语中的BEGIN/END是基础不异的,和C言语的框架是很类似的。我们可使用块往封装多条语句。在这个例子中,我们利用了多条设定会话变量的语句,然后完成了一些insert和select语句。假如你的历程体中有多条语句,那末你就必要BEGIN/END块了。BEGIN/END块也被称为复合语句,在这里你能够举行变量界说和流程把持。<pstyle="TEXT-INDENT:2em">未完待续...
表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。 |