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