MySQL中一般的指令、名称等等都不区分大小写,有符号(如-、*)的地方可以不加空格
\g和\G 的作用不同,虽然都表示分隔符,但是大写的\G可以使输出效果为 可以使每个字段打印到单独的行。
1、比较运算符中的不等运算符"<>" 和"!="
2、运算符like、regexp
like中“_”只匹配一个字符,可以代表任意一个字符,但是不能代表没有字符(长度不能为0);“%”可以匹配一个或多个字符,长度可以为0。
RegExp中正则表达式里,“.”只匹配一个字符,可以代表任意一个字符,但是不能代表没有字符(长度不能为0);“ * ”可以匹配多个该符号之前的字符,长度可以为0;“ + ”可以匹配多个该符号之前的字符,长度不可以为0,至少为1个,并且还得是前后的这两个字符紧贴着的。
distinct可以去除重复的
3、创建数据表中:
auto_increment 表示是否自动编号,每个表只能有一个auto_increment 列,并且必须被索引。
比如有些数据原来是写死的,没有记录到数据库中,后来由于需求变化需要做成动态管理,需要保存到数据库中,而原来有部分app_id已经被使用了,不能用于其它的,此时AUTO_INCREMENT就被派上用场了。比如app_id为10时用于我的网址(但是我的网址不需要保存到数据库中,因为每个用户必须显示此app,且不需要配置),如果创建表时不指定AUTO_INCREMENT=12,则app_id为10的值将用于新创建的app,将会发生岐义,所以一定要注意。
4、查询数据表时,group by 可以将数据划分到不同的组中,实现对记录的分组查询,所查询的列必须包含在分组的列中,目的是使查询到的数据没有矛盾。结合avg() 或 sum()使用,可以发挥最大的作用。也可按照多个字段进行分组,第一个为主要的,有相等的再按第二个分。也可以与group_concat()结合,将每个组中的所有字段值都显示出来。
而order by 可以对查询的结果进行升序和降序(DESC)排列,limit可以限定查询结果的记录数,控制其输出行数,第1个数字(编号1即从第2条记录),查询2个记录
将type字段的位置改到pass后面(bookname前面)(注意一定是type+类型varchar(20))
4、设置编码格式:set names gb2312;
5、count函数对于除“ * ”外的任何参数,返回所选择集合中非null值的行数;对于参数“ * ”,返回所选择集合中总的行数,包含null值的行;没有where子句的count(*)是经过内部优化的,可以快速返回表中的记录总数。
6、内连接,要求构成连接的每一部分的每个表都匹配,不匹配的行直接排除;最常见的例子是相等连接,即连接后的表中的某个字段与每个表中的都相同,最后的结果集只包含参加连接的表中与指定字段相符的行。
外连接,使用outer join将两个表连接起来,分左外连接(left join)、右外连接(right join)和全外连接3中
左外连接(left join)将左表中的所有数据分别与右表中的每条数据进行连接组合,返回的结果除内连接的数据外,还包括左表中不符合条件的数据,并在右表的相应列中添加null值。
右外连接(right join)将右表中的所有数据分别与左表中的每条数据进行连接组合,返回的结果除内连接的数据外,还包括右表中不符合条件的数据,并在左表的相应列中添加null值。
7、带in的子查询
exists表示是否存在,如果存在,再进行外面的查询,否则就不执行外层查询了
union是将所有的查询结果合并在一起,然后去除相同的记录;而union all只是简单的将结果合并在一起。并且一般是对于一列数据来说的,不能整个表合起来
8、为表取别名,不需要其他关键字,跟在表名后面即可。当表的名称特别长(并且在同一条语句中需要反复调用时)特别好用
为字段取别名。需要在其和别名之间加关键字as
9、MySQL索引的概念
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。上述SQL语句,在没有索引的情况下,数据库会遍历全部200条数据后选择符合条件的;而有了相应的索引之后,数据库会直接在索引中查找符合条件的选项。如果我们把SQL语句换成“SELECT * FROM article WHERE id=2000000”,那么你是希望数据库按照顺序读取完200万行数据以后给你结果还是直接在索引中定位呢?上面的两个图片鲜明的用时对比已经给出了答案(注:一般数据库默认都会为主键生成索引)。
索引分为聚簇索引和非聚簇索引两种,聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。
MySQL索引的类型
1. 普通索引
这是最基本的索引,它没有任何限制,比如上文中为title字段创建的索引就是一个普通索引,MyIASM中默认的BTREE类型的索引,也是我们大多数情况下用到的索引。
2. 唯一索引
与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值(注意和主键不同)。如果是组合索引,则列值的组合必须唯一,创建方法和普通索引类似。
3. 全文索引(FULLTEXT)
MySQL从3.23.23版开始支持全文索引和全文检索,FULLTEXT索引仅可用于 MyISAM 表;他们可以从CHAR、VARCHAR或TEXT列中作为CREATE TABLE语句的一部分被创建,或是随后使用ALTER TABLE 或CREATE INDEX被添加。对于较大的数据集,将你的资料输入一个没有FULLTEXT索引的表中,然后创建索引,其速度比把资料输入现有FULLTEXT索引的速度更为快。不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法。
4. 单列索引、多列索引
多个单列索引与单个多列索引的查询效果不同,因为执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。
5. 组合索引(最左前缀)
平时用的SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引。例如上表中针对title和time建立一个组合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立这样的组合索引,其实是相当于分别建立了下面两组组合索引:
–title,time
–title
为什么没有time这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这两列的查询都会用到该组合索引
1. 何时使用聚集索引或非聚集索引?
动作描述 | 使用聚集索引 | 使用非聚集索引 |
列经常被分组排序 | 使用 | 使用 |
返回某范围内的数据 | 使用 | 不使用 |
一个或极少不同值 | 不使用 | 不使用 |
小数目的不同值 | 使用 | 不使用 |
大数目的不同值 | 不使用 | 使用 |
频繁更新的列 | 不使用 | 使用 |
外键列 | 使用 | 使用 |
主键列 | 使用 | 使用 |
频繁修改索引列 | 不使用 | 使用 |
事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。其实这个具体用法我还不是很理解,只能等待后期的项目开发中慢慢学学了。
2. 索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
3. 使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
4. 索引列排序
MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
5. like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
6. 不要在列上进行运算
例如:select * from users where YEAR(adddate)<2007,将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:select * from users where adddate<’2007-01-01′。关于这一点可以围观:一个单引号引发的MYSQL性能损失。
最后总结一下,MySQL只对一下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些时候的like(不以通配符%或_开头的情形)。而理论上每张表里面最多可创建16个索引,不过除非是数据量真的很多,否则过多的使用索引也不是那么好玩的。
方法一:建立索引的方式:create on ()
普通索引
方法二:修改数据表结构的方式添加索引:alter table add
删除索引
由于插入记录时会导致索引更改,使速度降低,可以禁用索引、开启索引:
10、视图
视图:查看图形或文档的方式。视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。
视图是存储在数据库中的查询的SQL 语句,它主要出于两种原因:安全原因, 视图可以隐藏一些数据,如:社会保险基金表,可以用视图只显示姓名,地址,而不显示社会保险号和工资数等,另一原因是可使复杂的查询易于理解和使用。视图是从一个或多个表或视图中导出的表,其结构和数据是建立在对表的查询基础上的。和表一样,视图也是包括几个被定义的数据列和多个数据行,但就本质而言这些数据列和数据行来源于其所引用的表。
视图并没有保存内容。只是引用数据。那么,更新视图,其实就是以引用的方式操作了真实表with check option:对视图进行更新操作的时,需要检查更新后的值是否还是满足视图公式定义的条件。通俗点,就是所更新的结果是否还会在视图中存在。如果更新后的值不在视图范围内,就不允许更新如果创建视图的时候,没有加上with check option,更新视图中的某项数据的话,mysql并不会进行有效性检查。删掉了就删掉了。在视图中将看不到了。
用视图有什么好处呢?
①简化查询语句
比如:有一张商品表,我们经常要查每个栏目下商品的平均价格
select cat_id,avg(shop_price) from goods gropy by cat_id;
这时候我们就可以创建一张视图:
create view avgPrice as select cat_id,avg(shop_price) from goods gropy by cat_id;
创建完,以后我们要查每个栏目的平均价格时,只要这么写
select * from avgPrice;就可以了。
②可以进行权限控制
把表的权限封闭,但是开放相应的视图权限,视图里只开放部分数据列
比如我们的goods商品表,我们不想让别人看到我们的销售价格,这时候我们就可以把查看商品表的权限封闭,创建一张视图
create view showGoods as select goods_id,goods_name from goods;
不出现销售价格列就可以了。
③大数据分表时可以用到
比如表的行数据超过200万行时,速度就会变慢
可以把一张表的数据拆成4张表来存放
News表
newsid 1,2,3,4...
news1,news2,news3,news4表
把一张表的数据分散到4张表里,分散的方法有很多,
最常用的是id取模来计算
id%4+1=[1,2,3,4]
...
还可以用视图,把四张表形成一张视图
create view news as select * from news1 union select * from news2 union ...
5.视图的修改
alter view 视图名 as select 语句;
6.视图与表的关系
视图是表的查询结果,自然表的数据变了,会影响视图的结果
7.那么视图改变了会影响到表吗?
①视图的增删改也会影响表;
②但视图并不总是能增删改的;
视图的数据与表的数据一一对应时可以修改;
对于视图的insert还应注意:视图必须包含表中没有默认值的列。
8.视图的algorithm(运算规则)
algorithm = merge/temptable/undefined
merge:当引用视图时,引用视图的语句与定义视图的语句合并
意味着视图只是一个规则,语句规则,当查询视图时,把查询视图的语句
比如:where...那些与创建时的语句where子句等合并,分析,形成一条select语句。
举个列子:
我们先创建一张视图查询所有商品价格大于3000的商品
create view g2 as select goods_id,goods_name,shop_price from goods where shop_price > 3000;
然后我们再查询视图的时候,再加上一个where条件<5000
select * from g2 where shop_price < 5000
这时候它就会把两条语句合并分析最终形成这样一条select语句
select goods_id,goods_name,shop_price from goods where shop_price > 3000 and shop_price < 5000;
temptable:是根据创建语句瞬间创建一张临时表,然后查询视图的语句从该临时表查数据
merge 和 temptalbe 有一个显著的区别:
merge最终去查的还是goods表,而temptable去查的是虚拟表。
举个例子:我们要得到每个栏目下最贵的商品
首先我们创建一张视图查出每个栏目的商品按价格降序排序
create view lmj as select cat_id,goods_id,goods_name,shop_price from goods order by cat_id,shop_price desc;
这时候我们在查询这张视图的时候再对cat_id进行分组是不是就能得到我们想要的结果呢?
select * from lmj group by cat_id;
答案是不能的,因为它把我们的创建视图的语句和查询视图的语句合并成
select cat_id,goods_id,goods_name,shop_price from goods group by cat_id order by cat_id,shop_price desc;
而如果我们在创建视图的时候指定了它的运算规则为:temptable
create algorithm=temptable view lmj as select cat_id,goods_id,goods_name,shop_price from goods order by cat_id,shop_price desc;
然后我们再查询视图:select * frm lmj group by cat_id;就能得到我们想要的结果了。
它会先把select cat_id,goods_id,goods_name,shop_price from goods order by cat_id,shop_price desc;这句sql语句取到的结果放到一张临时表,然后我们再从这张临时表查自然能得到我们想要的结果了,而不是合并了再去查。
undefined:未定义,自动,让系统帮你选。
查看创建视图的权限:
均为yes,说明root用户具有创建和查询的权限。
创建视图:
查看视图信息(存储引擎、数据长度等均为null,说明是虚拟表):
查查看视图详细信息:
修改视图:
方法一:用create or replace,有视图时替换,无该视图存在时创建
方法二:alter
此时,只包含了一个a_sort属性
更新视图:
删除视图,只删除了视图的定义,不会删除数据:
11、数据完整性约束
完整性约束是对字段进行限制,从而符合该字段达到我们期望的效果
比如字段含有默认值,不能是NULL等
直观点说:如果插入的数据不满足限制要求,数据库管理系统就拒绝执行操作
关系模型中提供了实体完整性、参照完整性、用户定义的完整性3项规则。
#五种完整性约束:
#NOT NULL :非空约束,指定某列不能为空;
#UNIQUE : 唯一约束,指定某列或者几列组合不能重复
#PRIMARY KEY :主键,指定该列的值可以唯一地标识该列记录
#FOREIGN KEY :外键,指定该行记录从属于主表中的一条记录,主要用于参照完整性
#CHECK :检查,指定一个布尔表达式,用于指定对应的值必须满足该表达式(<span id="0_nwp" style="padding: 0px; width: auto; height: auto; float: none;"><a target=_blank id="0_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=18&is_app=0&jk=7407d41ccb31f6a&k=mysql&k0=mysql&kdi0=0&luki=7&mcpm=0&n=10&p=baidu&q=65035100_cpr&rb=0&rs=1&seller_id=1&sid=6a1fb3cc417d4007&ssp2=1&stid=9&t=tpclicked3_hc&td=1836545&tu=u1836545&u=http%3A%2F%2Fwww%2Ebubuko%2Ecom%2Finfodetail%2D903196%2Ehtml&urlid=0" target="_blank" mpid="0" style="padding: 0px; color: rgb(51, 51, 51); text-decoration: none;"><span style="padding: 0px; color: rgb(0, 0, 255); width: auto; height: auto;">mysql</span></a></span>不支持check约束)
设置表的主键
主键能够标识表中每条信息的唯一性,如同身份证号码和人的关系
人可以同名,但是身份证号码却是唯一的,
创建主键的目的在于快速查找到表中的某一条信息
可以参照http://www.cnblogs.com/nerxious/archive/2012/12/28/2837513.html
只有InnoDB引擎类型支持外键约束。
设置表的外键
表的外键与主键是相对应的,比如表A中的id是外键,表B中的id是主键
那么就可以称表B为父表,表A为子表
设置表外键的作用在于建立与父表的联系,比如表B中id为123的学生删除后,表A中id为123的记录也随着消失
这样做的目的在于保证表的完整性
mysql> create table student3(
-> id int primary key,
-> course_id int,
-> teacher varchar(20),
-> constraint fk foreign key(id,course_id)
-> references student2(id,course_id)
-> );
Query OK, 0 rows affected (0.12 sec)
这里创建student3表,constraint后面的fk是外键别名,foreign key也就是设置外键的字段
references后的内容表示父表,和父表中的主键
需要注意的是,父表中的主键不能为空,并且主键和外键的数据类型要一致
设置表的非空约束
非空性很好理解,就是设置表中字段的值不能为空(NULL)
如果在已经设置此约束性条件的字段中插入空值,数据库系统则会报错
mysql> create table student4(
-> id int not null,
-> name varchar(20),
-> sex boolean
-> );
Query OK, 0 rows affected (0.10 sec)
这里的not null就是约束条件
设置表的唯一性约束
唯一性是指表中该字段的值不能重复出现,设置表的唯一性约束
也就是给表中某个字段加上unique
mysql> create table student5(
-> id int unique,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.10 sec)
此处id字段便不可重复
设置表的属性值自动增加
auto_increment主要用于为表中插入的新记录自动生成唯一的ID
一个表只能有一个字段使用auto_increment约束
并且该字段必须为主键的一部分
mysql> create table student6(
-> id int primary key auto_increment,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.12 sec)
这里的id是主键,并且会自动增加id值,比如1,2,3,4……
需要注意的是,auto_increment约束的值必须是整数类型
设置表中属性的默认值
在表中插入一条新的记录时,如果没有为该字段赋值
那么数据库系统会自动为该字段赋上一条默认值
mysql> create table student7(
-> id int primary key,
-> score int default 0
-> );
Query OK, 0 rows affected (0.10 sec)
命名完整性约束
在各种完整性约束的定义说明之前加constraint子句
unique key(name)中,name没有用引号括起来
12、变量的应用,
返回值类型
全局变量前必须加@
变量赋值:
1、set = ;
2、select into from where ;
光标的使用
声明光标
declare cursor for
打开光标
open
使用光标
fetch into ;
关闭光标
close
13、触发器
创建+带多条执行语句
删除:
delete from where sid=7;
显示:
14、事件
查看事件是否开启
开启事件:
创建事件
修改事件(每30秒插入一次数据)
临时关闭事件:
删除事件:
15、备份数据库
导出整个数据库
导出文件默认是存在mysql\bin目录下
mysqldump -u 用户名 -p数据库名 >导出的文件名
mysqldump -u user_name -p123456 database_name >outfile_name.sql
“test.txt”中部分内容为:
"-- MySQL dump 10.13 Distrib 5.6.25, for Win64 (x86_64)
--
-- Host: localhost Database: test
-- ------------------------------------------------------
-- Server version 5.6.25
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `address`
--
DROP TABLE IF EXISTS `address`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `address` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`address` varchar(200) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `address` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `address`
--
LOCK TABLES `address` WRITE;
/*!40000 ALTER TABLE `address` DISABLE KEYS */;
/*!40000 ALTER TABLE `address` ENABLE KEYS */;
UNLOCK TABLES;"
以“--”开头的都是SQL语句的注释,以“/*!40101”等形式开头的内容是只有MySQL版本大于或等于指定的4.1.1版时才执行的语句。
导出多个数据库
备份所有数据库
或者密码后输
注意斜杠的朝向,是“/”,而非“\”,并且末尾不要加分号“;”
Html格式显示有问题:
mysqldump -u 用户名 -p --database数据库名 > D:abc.sql
(--database前面是两个短线)
mysql -u 用户名 -p --database 数据库名 < D:abc.sql
输入命令以后才会提示你输入密码的,输入命令的时候不需要输入密码.
2.导出一个表
mysqldump -u 用户名 -p数据库名表名>导出的文件名
mysqldump -u user_name -p database_name table_name >outfile_name.sql
3.导出一个数据库结构
mysqldump -u user_name -p -d –add-drop-table database_name> outfile_name.sql
-d 没有数据 –add-drop-table在每个create语句之前增加一个drop table
4.带语言参数导出
mysqldump -uroot -p –default-character-set=latin1–set-charset=gbk –skip-opt database_name > outfile_name.sql
例如,将aaa库备份到文件back_aaa中:
[root@test1 root]# cd/home/data/mysql
[root@test1 mysql]# mysqldump-u root -p --opt aaa > back_aaa
16、MySQL性能优化
查询MySQL数据库的性能:使用show status like ’value‘;
value可以为:connections、uptime、slow_queries等
使用explain、describe语句来分析查询语句
使用like关键字优化索引查询,第一个字符为百分号“%”时,索引不会被使用;如果“%”所匹配字符串的位置不是第一个位置,则索引会正常使用
查询语句只含or关键字时,需要两个字段都为索引,否则不会用索引查询;and关键字仍然可以用索引查询
由于插入记录时会导致索引更改,可以禁止索引、禁用唯一性检查、优化insert语句(一次插入多条记录、或用load data infile)等来提高速度。
分析表、检查表、优化表
检验高速缓存是否开启
使用高速缓存
17、用户和权限管理
创建,同时设定了密码
设定密码
当前账户直接set password=password(’mrss‘);
改名
赋予权利
撤销权利
取消账户
要想彻底的删除用户,必须使用DELETE语句将该用户的记录从MySQL数据库中的user表中删除。该语句的语法格式如下:
Delete from user whereuser = "user_name" and host = "host_name" ;
使用DELETE删除用户sss,代码如下:
mysql> use mysql
Database changed
mysql> delete from user where user='sss' and host='localhost' ;
mysql>flush privileges ;
Query OK, 1 row affected (0.02 sec)
其中,delete用于删除用户,flush告诉服务器重新加载授权表。
3、delimiter 分隔符
mysql> delimiter // “//”前面需加空格隔开,末尾不要符号 “;”
在 MySQL 命令行下运行 “delimiter //; ” 则 MySQL 的 delimiter 实际上是 “//;”,而不是我们所预想的 “//”
最后可以再用
mysql> delimiter ;将其恢复为正常的分号做分隔符
4、调用存储过程的语句(以下每句后面都要加分隔符(//或;):
call example_while(@s);
mysql>select @s;
5、repeat循环过程(until后面不要用分隔符,用在end repeat;)
use test;
delimiter //
create procedure example_repeat (out sum int)
begin
declare i int default 1;
declare s int default 0;
repeat
set s=s+i;
set i=i+1;
until i>100
end repeat;
set sum=s;
end
//
call example_repeat(@s);
select @s//