liu 发布的文章

文章目录

服务器配置

检查环境

如果安装

修改配置

启动服务

tortoise测试

文件不显示状态图标

服务器配置

名称配置

centos7.5-1804

svn版本1.7.14

内存8G

磁盘1T

检查环境

检查是否已经安装过svn了


[root@svngit ~]# svnserve --version

svnserve, version 1.7.14 (r1542130)

   compiled Apr 11 2018, 02:40:28


Copyright (C) 2013 The Apache Software Foundation.

This software consists of contributions made by many people; see the NOTICE

file for more information.

Subversion is open source software, see http://subversion.apache.org/


The following repository back-end (FS) modules are available:


* fs_base : Module for working with a Berkeley DB repository.

* fs_fs : Module for working with a plain file (FSFS) repository.


Cyrus SASL authentication is available.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

看来CentOS7.5已自带了SVN服务了…


上述检查的命令也可以用以下这条指令


[root@svngit ~]# rpm -qa | grep subversion

subversion-libs-1.7.14-14.el7.x86_64

subversion-1.7.14-14.el7.x86_64

1

2

3

如果安装

如果没有安装的话,直接使用以下方式安装


yum -y install subversion

1

安装后再使用svnserve --version查看版本信息


接下来创建版本库目录和版本库


[root@svngit ~]# mkdir -p /var/svn/svnrepos

[root@svngit ~]# cd /var/svn/svnrepos/

[root@svngit svnrepos]# svnadmin create /var/svn/svnrepos/zim

[root@svngit svnrepos]# ll

total 0

drwxr-xr-x. 6 root root 86 Sep  8 17:55 zim

1

2

3

4

5

6

进入zim目录,查看目录结构


[root@svngit zim]# ll

total 8

drwxr-xr-x. 2 root root  54 Sep  8 17:55 conf

drwxr-sr-x. 6 root root 233 Sep  8 17:55 db

-r--r--r--. 1 root root   2 Sep  8 17:55 format

drwxr-xr-x. 2 root root 231 Sep  8 17:55 hooks

drwxr-xr-x. 2 root root  41 Sep  8 17:55 locks

-rw-r--r--. 1 root root 229 Sep  8 17:55 README.txt

1

2

3

4

5

6

7

8

修改配置

进入版本库/conf目录内


# 用户的读写权限等

-rw-r--r--. 1 root root 1080 Sep  8 17:55 authz

# 用户的账号和密码信息

-rw-r--r--. 1 root root  309 Sep  8 17:55 passwd

# SVN服务器相关配置

-rw-r--r--. 1 root root 3090 Sep  8 17:55 svnserve.conf

1

2

3

4

5

6

其中,svnserver.conf配置


[general]

### The anon-access and auth-access options control access to the

### repository for unauthenticated (a.k.a. anonymous) users and

### authenticated users, respectively.

### Valid values are "write", "read", and "none".

### Setting the value to "none" prohibits both reading and writing;

### "read" allows read-only access, and "write" allows complete 

### read/write access to the repository.

### The sample settings below are the defaults and specify that anonymous

### users have read-only access to the repository, while authenticated

### users have read and write access to the repository.

anon-access = none

auth-access = write

### The password-db option controls the location of the password

### database file.  Unless you specify a path starting with a /,

### the file's location is relative to the directory containing

### this configuration file.

### If SASL is enabled (see below), this file will NOT be used.

### Uncomment the line below to use the default password file.

password-db = passwd

### The authz-db option controls the location of the authorization

### rules for path-based access control.  Unless you specify a path

### starting with a /, the file's location is relative to the the

### directory containing this file.  If you don't specify an

### authz-db, no path-based access control is done.

### Uncomment the line below to use the default authorization file.

authz-db = authz

### This option specifies the authentication realm of the repository.

### If two repositories have the same authentication realm, they should

### have the same password database, and vice versa.  The default realm

### is repository's uuid.

realm = /var/svn/svnrepos

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

passwd文件中增加用户密码信息


[users]

# harry = harryssecret

# sally = sallyssecret

zhangsan = zhangsan

lisi = lisi

wangwu = wangwu

1

2

3

4

5

6

在authz文件中配置上述用户的分组情况和操作权限


[groups]

# harry_and_sally = harry,sally

# harry_sally_and_joe = harry,sally,&joe

group1 = zhangsan,lisi

group2 = wangwu

# [/foo/bar]

# harry = rw

# &joe = r

# * =


# [repository:/baz/fuz]

# @harry_and_sally = rw

# * = r

# 根目录

[/]

@group1 = rw

@group2 = r

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

启动服务

[root@svngit conf]# svnserve -d -r /var/svn/svnrepos

[root@svngit conf]# ps -aux | grep svn

root     26099  0.0  0.0 180716   804 ?        Ss   13:46   0:00 svnserve -d -r /var/svn/svnrepos

1

2

3

开启防火墙

SVN端口默认为3690,若Linux开启了防火墙,需开启默认端口

开启端口:firewall-cmd --zone=public --add-port=3690/tcp --permanent

重启防火墙:firewall-cmd --reload


[root@svngit conf]# netstat -antp | grep 3690

tcp        0      0 0.0.0.0:3690            0.0.0.0:*               LISTEN      26099/svnserve      

[root@svngit conf]# firewall-cmd --zone=public --add-port=3690/tcp --permanent

success

[root@svngit conf]# firewall-cmd --reload

success

1

2

3

4

5

6

tortoise测试

win64位下载地址:

https://osdn.net/projects/tortoisesvn/storage/1.14.0/Application/TortoiseSVN-1.14.0.28885-x64-svn-1.14.0.msi/




在Checkout的目录内创建测试文件和文件夹




还没有配置用户名和密码


之后再次提交可提交成功,使用wangwu的用户,则失败,因为wangwu配置时没有配置写权限。



文件不显示状态图标

如下,也不知道各个文件的状态是什么


解决办法:

找到下载的安装包,双击运行,到如下步骤时,点击中间的repair,修复一下,修复完小图标就显示出来了。



————————————————

版权声明:本文为CSDN博主「再看我把你吃掉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/zz_aiytag/article/details/108462450


1.安装svn服务器端软件

从镜像服务器或者YUM源下载安装SVN服务器软件:yum install subversion     

mkdir /usr/local/svn     //创建SVN安装目录

chmod -R 777 svn      //修改目录权限为777

svnadmin create /usr/local/svn/sunny  //创建一个SVN版本仓库sunny(sunny可以自定义)

cd  /usr/local/svn/sunny/conf    //进入sunny版本仓库下的配置文件目录

 

下面要修改这个目录下的三个配置文件

(1)vi svnserve.conf    //配置版本库信息和用户文件和用户密码文件的路径、版本库路径,把

# anon-access = read

# auth-access = write

# password-db = passwd

//这四行,前面的#号和空格去掉(注意去掉#要顶格写,不要留有多余空格),变成

anon-access = none      //匿名访问,改成none

auth-access = write

password-db = passwd

realm = sunny           //改成自己的版本库名称

保存退出

 

(2)vi authz     //文件,创建SVN组和组用户的权限

[group]

sunny = gep,wce //创建一个sunny的组,并指定两个用户gepwce

 

[/]             //制定根目录下的权限

@sunny = rw     //sunny组用户权限为读写

* = r           //其他用户只有读权限

保存退出

 

(3) vi passwd   //创建或修改用户密码

[users]

gep = 123456    //用户名为gep的用户的密码为123456

wce = 123456    //。。。

保存退出

 

 

启动SVN服务器:

//这里采用多版本库的方式启动  

svnserve -d -r /usr/local/svn/

如果是单版本库可以添加一行

svnserve -d -r /usr/local/svn/sunny

然后要设置自启动

` 打开自启动文件添加

/usr/bin/svnserve -d -r /usr/local/svn/

 

到此为止可以从服务端检出文件了.

 

svn命令:

netstat -tnl |grep :3690   查看svn是否启动

安装成功!

 

 

 

ps aux |grep  svn  查找所有svn启动的进程

kill -9 2505    杀死2505这个查找到的svn进程

 

 

svn checkout svn://172.19.5.2/sunny /data0/htdocs/blog  //检出一份版本库文件到指定目录

svn up                        //更新文件

 

自动更新

vi /usr/local/svn/sunny/hooks/post-commit中加入

 

#!/bin/sh

#设置一些变量

SVN=/usr/bin/svn

WEB=/home/testsvn #要更新的目录

export.UTF-8

$SVN update $WEB --username xxx --password xxx

 

 

其中SVN=右边改成 svn 命令位置 一般默认为/usr/bin/svn

    WEB=右边改成你实际的web目录

赋予可执行权限

chmod 777 /usr/local/svn/sunny/hooks/post-commit

安装完毕

 

 

=========================================================================

其他操作

 

#svn commit -m "注释" xxx.php  //提交文件

svn ci -m'aaa' test.php       //提交文件

 

#svn add file               //新建文件并添加到svn

svn add *.php               //(添加当前目录下所有的php文件)

svn delete test.php         //删除test.php

svn log test.php            //查看test文件的log信息

svn cleanup                 //清理当前目录

 

 

 

svn switch --relocate svn://192.168.1.253  svn://172.19.10.250      //重新定位SVN版本库地址

 

 

 

 

// SVN版本库起动方式,现在SVN下面有 sunnytest 两个版本库

1:单版本库起动    svnserve -d -r /usr/local/svn/sunny

2:多版本库起动    svnserve -d -r /usr/local/svn

区别在于起动svn时候的命令中的启动参数-r指定的目录。

 

限制不同的用户对不同的版本库操作权限,修改版本库中的conf目录下的 authz文件

 

以配置 sunny 版本库为例

vi authz

[groups]

teacher = sunny,sunny1

[sunny:/]             //指定版本库跟目录下的权限

@teacher = rw     //teacher组用户权限为读写

* = r           //其他用户只有读权限

保存退出

 

vi passwd 设置组中用户的账号和密码

[users]

sunny  = 123456

sunny1 = 123456


JeecgBoot是一款基于BPM的低代码平台!

20210617220016265.png

前后端分离架构 SpringBoot 2.x,SpringCloud,Ant Design&Vue,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发! JeecgBoot引领新低代码开发模式 OnlineCoding-> 代码生成器-> 手工MERGE, 帮助Java项目解决70%的重复工作,让开发更多关注业务,既能快速提高效率,节省研发成本,同时又不失灵活性!一系列低代码能力:Online表单、Online报表、Online图表、表单设计、流程设计、报表设计、大屏设计 等等.


一. DataX 3.0概览

DataX 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。

datax_why_new


  • 设计理念

    为了解决异构数据源同步问题,DataX将复杂的网状的同步链路变成了星型数据链路,DataX作为中间传输载体负责连接各种数据源。当需要接入一个新的数据源的时候,只需要将此数据源对接到DataX,便能跟已有的数据源做到无缝数据同步。

  • 当前使用现状

    DataX在阿里巴巴集团内被广泛使用,承担了所有大数据的离线同步业务,并已持续稳定运行了6年之久。目前每天完成同步8w多道作业,每日传输数据量超过300TB。

此前已经开源DataX1.0版本,此次介绍为阿里云开源全新版本DataX3.0,有了更多更强大的功能和更好的使用体验。Github主页地址:https://github.com/alibaba/DataX

二、DataX3.0框架设计

datax_framework_new


DataX本身作为离线数据同步框架,采用Framework + plugin架构构建。将数据源读取和写入抽象成为Reader/Writer插件,纳入到整个同步框架中。

  • Reader:Reader 为数据采集模块,负责采集数据源的数据,将数据发送给Framework。

  • Writer: Writer为数据写入模块,负责不断向Framework取数据,并将数据写入到目的端。

  • Framework:Framework用于连接reader和writer,作为两者的数据传输通道,并处理缓冲,流控,并发,数据转换等核心技术问题。

三. DataX3.0插件体系

经过几年积累,DataX目前已经有了比较全面的插件体系,主流的RDBMS数据库、NOSQL、大数据计算系统都已经接入。DataX目前支持数据如下:

类型数据源Reader(读)Writer(写)文档
RDBMS 关系型数据库MySQL

Oracle

SQLServer

PostgreSQL

DRDS

达梦

通用RDBMS(支持所有关系型数据库)
阿里云数仓数据存储ODPS

ADS

OSS

OCS
NoSQL数据存储OTS

Hbase0.94

Hbase1.1

MongoDB

Hive
无结构化数据存储TxtFile

FTP

HDFS

Elasticsearch

DataX Framework提供了简单的接口与插件交互,提供简单的插件接入机制,只需要任意加上一种插件,就能无缝对接其他数据源。详情请看:DataX数据源指南

四、DataX3.0核心架构

DataX 3.0 开源版本支持单机多线程模式完成同步作业运行,本小节按一个DataX作业生命周期的时序图,从整体架构设计非常简要说明DataX各个模块相互关系。

datax_arch


核心模块介绍:

  1. DataX完成单个数据同步的作业,我们称之为Job,DataX接受到一个Job之后,将启动一个进程来完成整个作业同步过程。DataX Job模块是单个作业的中枢管理节点,承担了数据清理、子任务切分(将单一作业计算转化为多个子Task)、TaskGroup管理等功能。

  2. DataXJob启动后,会根据不同的源端切分策略,将Job切分成多个小的Task(子任务),以便于并发执行。Task便是DataX作业的最小单元,每一个Task都会负责一部分数据的同步工作。

  3. 切分多个Task之后,DataX Job会调用Scheduler模块,根据配置的并发数据量,将拆分成的Task重新组合,组装成TaskGroup(任务组)。每一个TaskGroup负责以一定的并发运行完毕分配好的所有Task,默认单个任务组的并发数量为5。

  4. 每一个Task都由TaskGroup负责启动,Task启动后,会固定启动Reader—>Channel—>Writer的线程来完成任务同步工作。

  5. DataX作业运行起来之后, Job监控并等待多个TaskGroup模块任务完成,等待所有TaskGroup任务完成后Job成功退出。否则,异常退出,进程退出值非0

DataX调度流程:

举例来说,用户提交了一个DataX作业,并且配置了20个并发,目的是将一个100张分表的mysql数据同步到odps里面。 DataX的调度决策思路是:

  1. DataXJob根据分库分表切分成了100个Task。

  2. 根据20个并发,DataX计算共需要分配4个TaskGroup。

  3. 4个TaskGroup平分切分好的100个Task,每一个TaskGroup负责以5个并发共计运行25个Task。

五、DataX 3.0六大核心优势

  • 可靠的数据质量监控

    • 完美解决数据传输个别类型失真问题

      DataX旧版对于部分数据类型(比如时间戳)传输一直存在毫秒阶段等数据失真情况,新版本DataX3.0已经做到支持所有的强数据类型,每一种插件都有自己的数据类型转换策略,让数据可以完整无损的传输到目的端。

    • 提供作业全链路的流量、数据量�运行时监控

      DataX3.0运行过程中可以将作业本身状态、数据流量、数据速度、执行进度等信息进行全面的展示,让用户可以实时了解作业状态。并可在作业执行过程中智能判断源端和目的端的速度对比情况,给予用户更多性能排查信息。

    • 提供脏数据探测

      在大量数据的传输过程中,必定会由于各种原因导致很多数据传输报错(比如类型转换错误),这种数据DataX认为就是脏数据。DataX目前可以实现脏数据精确过滤、识别、采集、展示,为用户提供多种的脏数据处理模式,让用户准确把控数据质量大关!

  • 丰富的数据转换功能

    DataX作为一个服务于大数据的ETL工具,除了提供数据快照搬迁功能之外,还提供了丰富数据转换的功能,让数据在传输过程中可以轻松完成数据脱敏,补全,过滤等数据转换功能,另外还提供了自动groovy函数,让用户自定义转换函数。详情请看DataX3的transformer详细介绍。

  • 精准的速度控制

    还在为同步过程对在线存储压力影响而担心吗?新版本DataX3.0提供了包括通道(并发)、记录流、字节流三种流控模式,可以随意控制你的作业速度,让你的作业在库可以承受的范围内达到最佳的同步速度。

    "speed": {
       "channel": 5,
       "byte": 1048576,
       "record": 10000
    }
  • 强劲的同步性能

    DataX3.0每一种读插件都有一种或多种切分策略,都能将作业合理切分成多个Task并行执行,单机多线程执行模型可以让DataX速度随并发成线性增长。在源端和目的端性能都足够的情况下,单个作业一定可以打满网卡。另外,DataX团队对所有的已经接入的插件都做了极致的性能优化,并且做了完整的性能测试。性能测试相关详情可以参照每单个数据源的详细介绍:DataX数据源指南

  • 健壮的容错机制

    DataX作业是极易受外部因素的干扰,网络闪断、数据源不稳定等因素很容易让同步到一半的作业报错停止。因此稳定性是DataX的基本要求,在DataX 3.0的设计中,重点完善了框架和插件的稳定性。目前DataX3.0可以做到线程级别、进程级别(暂时未开放)、作业级别多层次局部/全局的重试,保证用户的作业稳定运行。

    • 线程内部重试

      DataX的核心插件都经过团队的全盘review,不同的网络交互方式都有不同的重试策略。

    • 线程级别重试

      目前DataX已经可以实现TaskFailover,针对于中间失败的Task,DataX框架可以做到整个Task级别的重新调度。

  • 极简的使用体验

    • 传输过程中打印传输速度、进度等

      datax_run_speed


    • 传输过程中会打印进程相关的CPU、JVM等

      datax_run_cpu


    • 在任务结束之后,打印总体运行情况

      datax_end_info

    • 易用

      下载即可用,支持linux和windows,只需要短短几步骤就可以完成数据的传输。请点击:Quick Start

    • 详细

      DataX在运行日志中打印了大量信息,其中包括传输速度,Reader、Writer性能,进程CPU,JVM和GC情况等等。



作者:承诺一时的华丽
链接:https://www.jianshu.com/p/9ae2d9e35e3a
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


例子:

当前有三张表A、B、C其中A和B是一对多关系,B和C是一对多关系,现在需要将B中A表的主键存到C中;
常规思路就是将B中查询出来然后通过一个update语句来更新C表就可以了,但是B表中有2000多条数据,
难道要执行2000多次?显然是不现实的;最终找到写一个存储过程然后通过循环来更新C表,
然而存储过程中的写法用的就是游标的形式。

【简介】

    游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。

    游标充当指针的作用。

    尽管游标能遍历结果中的所有行,但他一次只指向一行。

    游标的作用就是用于对查询数据库所返回的记录进行遍历,以便进行相应的操作。

【用法】

    一、声明一个游标: declare 游标名称 CURSOR for table;(这里的table可以是你查询出来的任意集合)
    二、打开定义的游标:open 游标名称;
    三、获得下一行数据:FETCH  游标名称 into testrangeid,versionid;
    四、需要执行的语句(增删改查):这里视具体情况而定
    五、释放游标:CLOSE 游标名称;
  注:mysql存储过程每一句后面必须用;结尾,使用的临时字段需要在定义游标之前进行声明。

【实例】

复制代码

-  BEGIN  
  --定义变量  declare testrangeid BIGINT;  
declare versionid BIGINT;   
declare done int;  
--创建游标,并存储数据  declare cur_test CURSOR for   
   select id as testrangeid,version_id as versionid from tp_testrange;  
--游标中的内容执行完后将done设置为1  
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;   
--打开游标  open cur_test;  
--执行循环    posLoop:LOOP  
--判断是否结束循环  
        IF done=1 THEN    
      LEAVE posLoop;  
    END IF;   
--取游标中的值  
    FETCH  cur_test into testrangeid,versionid;  
--执行更新操作  
    update tp_data_execute set version_id=versionid where testrange_id = testrangeid;  
  END LOOP posLoop;  
--释放游标  CLOSE cur_test;  
  
END  -

复制代码

例子2:

我们现在要用存储过程做一个功能,统计iphone的总库存是多少,并把总数输出到控制台。

复制代码

--在windows系统中写存储过程时,如果需要使用declare声明变量,需要添加这个关键字,否则会报错。  delimiter //  drop procedure if exists StatisticStore;  
CREATE PROCEDURE StatisticStore()  
BEGIN  
    --创建接收游标数据的变量  
    declare c int;  
    declare n varchar(20);  
    --创建总数变量  
    declare total int default 0;  
    --创建结束标志变量  
    declare done int default false;  
    --创建游标  
    declare cur cursor for select name,count from store where name = 'iphone';  
    --指定游标循环结束时的返回值  
    declare continue HANDLER for not found set done = true;  
    --设置初始值  
    set total = 0;  
    --打开游标  
    open cur;  
    --开始循环游标里的数据      read_loop:loop  
    --根据游标当前指向的一条数据  
    fetch cur into n,c;  
    --判断游标的循环是否结束  
    if done then  
        leave read_loop;    --跳出游标循环  
    end if;  
    --获取一条数据时,将count值进行累加操作,这里可以做任意你想做的操作,  
    set total = total + c;  
    --结束游标循环  
    end loop;  
    --关闭游标  
    close cur;  
  
    --输出结果  
    select total;  
END;  
--调用存储过程  call StatisticStore();

复制代码

fetch是获取游标当前指向的数据行,并将指针指向下一行,当游标已经指向最后一行时继续执行会造成游标溢出。
使用loop循环游标时,他本身是不会监控是否到最后一条数据了,像下面代码这种写法,就会造成死循环;

read_loop:loop  
fetch cur into n,c;  
set total = total+c;  
end loop;

在MySql中,造成游标溢出时会引发mysql预定义的NOT FOUND错误,所以在上面使用下面的代码指定了当引发not found错误时定义一个continue 的事件,指定这个事件发生时修改done变量的值。

declare continue HANDLER for not found set done = true;

所以在循环时加上了下面这句代码:

--判断游标的循环是否结束  if done then  
    leave read_loop;    --跳出游标循环  end if;

如果done的值是true,就结束循环。继续执行下面的代码

使用方式

游标有三种使用方式:
第一种就是上面的实现,使用loop循环;
第二种方式如下,使用while循环:

复制代码

drop procedure if exists StatisticStore1;  
CREATE PROCEDURE StatisticStore1()  
BEGIN  
    declare c int;  
    declare n varchar(20);  
    declare total int default 0;  
    declare done int default false;  
    declare cur cursor for select name,count from store where name = 'iphone';  
    declare continue HANDLER for not found set done = true;  
    set total = 0;  
    open cur;  
    fetch cur into n,c;  
    while(not done) do  
        set total = total + c;  
        fetch cur into n,c;  
    end while;  
      
    close cur;  
    select total;  
END;  
  
call StatisticStore1();

复制代码

第三种方式是使用repeat执行:

复制代码

drop procedure if exists StatisticStore2;  
CREATE PROCEDURE StatisticStore2()  
BEGIN  
    declare c int;  
    declare n varchar(20);  
    declare total int default 0;  
    declare done int default false;  
    declare cur cursor for select name,count from store where name = 'iphone';  
    declare continue HANDLER for not found set done = true;  
    set total = 0;  
    open cur;  
    repeat  
    fetch cur into n,c;  
    if not done then  
        set total = total + c;  
    end if;  
    until done end repeat;  
    close cur;  
    select total;  
END;  
  
call StatisticStore2();

复制代码

游标嵌套

在mysql中,每个begin end 块都是一个独立的scope区域,由于MySql中同一个error的事件只能定义一次,如果多定义的话在编译时会提示Duplicate handler declared in the same block。

复制代码

drop procedure if exists StatisticStore3;  
CREATE PROCEDURE StatisticStore3()  
BEGIN  
    declare _n varchar(20);  
    declare done int default false;  
    declare cur cursor for select name from store group by name;  
    declare continue HANDLER for not found set done = true;  
    open cur;  
    read_loop:loop  
    fetch cur into _n;  
    if done then  
        leave read_loop;  
    end if;  
    begin  
        declare c int;  
        declare n varchar(20);  
        declare total int default 0;  
        declare done int default false;  
        declare cur cursor for select name,count from store where name = 'iphone';  
        declare continue HANDLER for not found set done = true;  
        set total = 0;  
        open cur;  
        iphone_loop:loop  
        fetch cur into n,c;  
        if done then  
            leave iphone_loop;  
        end if;  
        set total = total + c;  
        end loop;  
        close cur;  
        select _n,n,total;  
    end;  
    begin  
            declare c int;  
            declare n varchar(20);  
            declare total int default 0;  
            declare done int default false;  
            declare cur cursor for select name,count from store where name = 'android';  
            declare continue HANDLER for not found set done = true;  
            set total = 0;  
            open cur;  
            android_loop:loop  
            fetch cur into n,c;  
            if done then  
                leave android_loop;  
            end if;  
            set total = total + c;  
            end loop;  
            close cur;  
        select _n,n,total;  
    end;  
    begin  
      
    end;  
    end loop;  
    close cur;  
END;  
  
call StatisticStore3();

复制代码

上面就是实现一个嵌套循环,当然这个例子比较牵强。凑合看看就行。

动态SQL

Mysql 支持动态SQL的功能

set @sqlStr='select * from table where condition1 = ?';  
prepare s1 for @sqlStr;  
--如果有多个参数用逗号分隔  execute s1 using @condition1;  
--手工释放,或者是 connection 关闭时, server 自动回收  deallocate prepare s1;