精华内容
下载资源
问答
  • 如下存储过程使用游标遍历所有数据: CREATE OR REPLACE PROCEDURE "CFFTEST"."SELECT_STUDENT"("id" IN INT) AS myId int; myName varchar(50); cursor myCursor is select id, name from cfftest.student; ...
  • 我们在处理存储过程中的结果集时,可以使用游标,因为游标允许我们迭代查询返回的一组行,并相应地处理每行。mysql的游标为只读,不可滚动和敏感三种模式,我们来看下: 只读:无法通过光标更新基础表的数据。 ...
  • 第一种情况是返回的游标是某个具体的表或视图的数据,如: SQL-Code: 代码如下: CREATE OR REPLACE PROCEDURE P_TESTA ( PRESULT OUT SYS_REFCURSOR ) AS BEGIN OPEN PRESULT FOR SELECT * FROM USERS; END P_TESTA;...
  • mysql 存储过程中游标After my previous article on Stored Procedures was published on SitePoint, I received quite a number of comments. One of them suggested further elaboration on CURSOR, an important ...

    mysql 存储过程中游标

    After my previous article on Stored Procedures was published on SitePoint, I received quite a number of comments. One of them suggested further elaboration on CURSOR, an important feature in Stored Procedures.

    上一篇有关存储过程的文章在SitePoint 发布之后,我收到了很多评论。 其中一位建议进一步详细说明CURSOR,这是存储过程的重要功能。

    As cursors are a part of a Stored Procedure, we will elaborate a bit more on SP in this article as well. In particular, we will see how to return a dataset from an SP.

    由于游标是存储过程的一部分,因此我们还将在本文中详细介绍SP。 特别是,我们将看到如何从SP返回数据集。

    什么是游标? (What is a CURSOR?)

    A cursor can’t be used by itself in MySQL. It is an essential component in stored procedures. I would be inclined to treat a cursor as a “pointer” in C/C++, or an iterator in PHP’s foreach statement.

    游标本身不能在MySQL中使用。 它是存储过程中的重要组成部分。 我倾向于将游标视为C / C ++中的“指针”,或者视为PHP的foreach语句中的迭代器。

    With cursors, we can traverse a dataset and manipulate each record to accomplish certain tasks. When such an operation on a record can also be done in the PHP layer, it saves data transfer amounts as we can just return the processed aggregation/statistical result back to the PHP layer (thus eliminating the selectforeach – manipulation process at the client side).

    使用游标,我们可以遍历数据集并处理每条记录以完成某些任务。 当这样的记录操作也可以在PHP层中完成时,它可以节省数据传输量,因为我们只需将处理后的聚合/统计结果返回给PHP层即可(从而省去了客户端的select - foreach操作过程)侧)。

    Since a cursor is implemented in a stored procedure, it has all the benefits (and limitations) of an SP (access control, pre-compiled, hard to debug, etc).

    由于游标是在存储过程中实现的,因此游标具有SP的所有优点(和局限性)(访问控制,预编译,难以调试等)。

    The official documentation on cursors is located here. It contains only four commands that are related to cursor declaration, opening, closing, and fetching. As mentioned above, we will also touch on some other stored procedure statements. Let’s get started.

    游标的官方文档位于此处 。 它仅包含四个与游标声明,打开,关闭和获取有关的命令。 如上所述,我们还将介绍其他一些存储过程语句。 让我们开始吧。

    一个现实世界的问题 (A real world question)

    My personal website has a page showing the scores of my favorite NBA team: LA Lakers. The table structure behind it is straightforward:

    我的个人网站上有一个页面,显示我最喜欢的NBA球队:洛杉矶湖人队的得分。 它后面的表结构很简单:

    alt

    Fig 1. The Lakers matches status table structure

    图1.湖人队比赛状态表结构

    I have been updating this table since 2008. Some of the latest records showing Lakers’ 2013-14 season are shown below:

    自2008年以来,我一直在更新此表。一些显示湖人队2013-14赛季的最新记录如下:

    alt

    Fig 2. The Lakers matches status table data (partial) for 2013-2014 season

    图2.湖人队2013-2014赛季比赛状态表数据(部分)

    (I am using MySQL Workbench as the GUI tool to manage my MySQL databases. You can use your favorite tool.)

    (我使用MySQL Workbench作为管理我MySQL数据库的GUI工具。您可以使用自己喜欢的工具。)

    Well, I have to admit Lakers are not playing very well these days. 6 consecutive losses up to Jan 15th. I get this “6 consecutive losses” by manually counting from the last played match all the way up (towards earlier games) and see how long an “L” (meaning a loss) in winlose column can appear. This is certainly doable but if the requirement becomes more complicated in a larger table, it takes more time and is more error prone.

    好吧,我不得不承认湖人最近的表现并不好。 截至1月15日,连续6次亏损。 通过手动从上次比赛开始一直计数(直到较早的比赛),我得到了“连续6次亏损”,并看到在winlose列中出现“ L”(意味着亏损)多winlose 。 这当然是可行的,但是如果需求在更大的表中变得更加复杂,则将花费更多的时间并且更容易出错。

    Can we do this with a single SQL statement? I am not an SQL expert and I haven’t been able to figure out how to achieve the desired result (“6 consecutive losses”) from one SQL statement. The input of gurus will be highly appreciated – leave it in the comments below.

    我们可以用一个SQL语句来做到这一点吗? 我不是SQL专家,我无法从一个SQL语句中弄清楚如何实现期望的结果(“连续6次丢失”)。 大师的意见将受到高度赞赏–留在下面的评论中。

    Can we do this in PHP? Yes, of course. We can retrieve the game data (particularly, the winlose column) for current season and do a traverse on the records to calculate the current longest win/lose streak. But to do that, we will have to grab all data for that year and most of the data will be wasted (as it is not likely for a team to have a win/lose streak for more than 20+ games in a 82-game regular season). However, we don’t know how many records should be retrieved into PHP to determine the streak, so this waste is a must. And finally, if the current win/lose streak is the only thing we want to know from that table, why pull all the raw data?

    我们可以用PHP做到吗? 当然是。 我们可以检索当前赛季的比赛数据(特别是winlose列),并在记录上进行遍历以计算当前最长的获胜/失利连胜纪录。 但是要做到这一点,我们将必须获取当年的所有数据,并且大部分数据都将被浪费(因为一支球队在82场比赛中赢得20场以上比赛的胜利/失败连胜的可能性不大常规赛)。 但是,我们不知道应该从PHP中检索多少记录来确定条纹,因此这种浪费是必须的。 最后,如果当前唯一要从该表中获胜的消息是,为什么要提取所有原始数据?

    Can we do this via other means? Yes, it is possible. For example, we can create a redundant table specifically designed to store the current win/lose streak. Every insertion of the record will update that table too. But this is way too cumbersome and too error prone.

    我们可以通过其他方式做到吗? 是的,有可能。 例如,我们可以创建一个冗余表,专门用于存储当前的赢/输。 每次插入记录也会更新该表。 但这太麻烦了并且容易出错。

    So, what is a better way to achieve this result?

    那么,有什么更好的方法来达到这个结果呢?

    在存储过程中使用游标 (Using Cursor in a Stored Procedure)

    As the name of this article suggests, we will see a better alternative (in my view) to solve this problem: using cursor in a Stored Procedure.

    就像本文的名称所暗示的那样,(在我看来)我们将看到一个更好的解决方案:在存储过程中使用游标。

    Let’s create the first SP in MySQL Workbench as follows:

    让我们在MySQL Workbench中创建第一个SP,如下所示:

    DELIMITER $$
    
    CREATE DEFINER=`root`@`localhost` PROCEDURE `streak`(in cur_year int, out longeststreak int, out status char(1))
    BEGIN
        declare current_win char(1);
        declare current_streak int;
        declare current_status char (1);
    
        declare cur cursor for select winlose from lakers where year=cur_year and winlose<>'' order by id desc;
    
        set current_streak=0;
    
        open cur;
    
        fetch cur into current_win;
        set current_streak = current_streak +1;
    
        start_loop: loop
            fetch cur into current_status;
                if current_status <> current_win then 
                    leave start_loop;
                else
                    set current_streak=current_streak+1;
                end if;
    
        end loop;
    
        close cur;
    
        select current_streak into longeststreak;
        select current_win into `status`;
    END

    In this SP, we have one input parameter and two output parameters. This defines the signature of the SP.

    在此SP中,我们有一个输入参数和两个输出参数。 这定义了SP的签名。

    In the SP body, we also declared a few local variables to hold the streak status (win or lose, current_win), current streak and current win/lose status for a particular match.

    在SP主体中,我们还声明了一些局部变量来保存特定比赛的连胜状态(赢或输, current_win ),当前连胜和当前赢/输状态。

    declare cur cursor for select winlose from lakers where year=cur_year and winlose<>'' order by id desc;

    The above line is the cursor declaration. We declared a cursor named cur and the dataset bind to that cursor is the win/lose status for those matches played (thus its winlose column is either “W” or “L” instead of nothing) in a particular year ordered by id (the latest played games will have the highest ID) descending.

    上一行是游标声明。 我们声明了一个名为cur的游标,并且绑定到该游标的数据集是按id排序的特定年份中所进行的那些比赛的获胜/失败状态(因此其winlose “ W”或“ L”而不是什么)最新玩过的游戏的ID最高)降序。

    Though not displayed explicitly, we can imagine that this dataset will contain a series of “L”s and “W”s. Based on the data shown in Figure 2 above, it should be: “LLLLLLWLL…” (6 Ls, 1 Ws, etc).

    尽管没有明确显示,但我们可以想象该数据集将包含一系列“ L”和“ W”。 根据上面图2中显示的数据,它应该是:“ LLLLLLWLL…”(6 L,1 W等)。

    To calculate the win/lose streak, we begin with the latest (and the first in the dataset) match data. When a cursor is opened, it always starts at the first record in the associated dataset.

    为了计算赢/输连胜,我们从最新的(也是数据集中的第一个)比赛数据开始。 打开游标时,它总是从关联数据集中的第一条记录开始。

    After the first data is grabbed, the cursor will move to the next record. In this way, a cursor behaves very much like a queue, traversing the dataset in a FIFO (First In First Out) manner. This is exactly what we wanted.

    抓取第一个数据后,光标将移至下一个记录。 这样,游标的行为非常类似于队列,以FIFO(先进先出)的方式遍历数据集。 这正是我们想要的。

    After getting the current win/lose status and set the streak number, we continue to loop through (traverse) the remainder of the dataset. With each loop iteration, the cursor will “point” to the next record until we break the loop or all the records are consumed.

    在获得当前的输赢状态并设置连胜号码后,我们继续遍历(遍历)数据集的其余部分。 每次循环迭代时,游标将“指向”下一条记录,直到我们中断循环或消耗完所有记录为止。

    If the next win/lose status is the same as the current win/lose status, it means the streak goes on and we increase the streak number by 1 and continue the traversing; otherwise, it means the streak discontinues and we can leave the loop earlier.

    如果下一个获胜/失败状态与当前获胜/失败状态相同,则表示连胜继续,我们将连胜数增加1并继续遍历; 否则,这意味着条纹将中断,我们可以更早地退出循环。

    Finally, we close the cursor and release the resources. Then we return the desired output.

    最后,我们关闭游标并释放资源。 然后,我们返回所需的输出。

    Next, we can enhance the access control of the SP as described in my previous article.

    接下来,我们可以按照我之前的文章中所述,增强对SP的访问控制。

    To test the output of this SP, we will write a short PHP script:

    为了测试此SP的输出,我们将编写一个简短PHP脚本:

    <?php
    $dbms = 'mysql';
    
    $host = 'localhost';
    $db = 'sitepoint';
    $user = 'root';
    $pass = 'your_pass_here';
    $dsn = "$dbms:host=$host;dbname=$db";
    
    $cn=new PDO($dsn, $user, $pass);
    
    $cn->exec('call streak(2013, @longeststreak, @status)');
    $res=$cn->query('select @longeststreak, @status')->fetchAll();
    
    var_dump($res); //Dump the output here to get a raw view of the output
    
    $win=$res[0]['@status']='L'?'Loss':'Win';
    $streak=$res[0]['@longeststreak'];
    
    echo "Lakers is now $streak consecutive $win.\n";

    This will output something like the following figure:

    这将输出如下图所示的内容:

    alt

    (This output is based on Lakers’ match up to Jan 15th, 2014.)

    (此输出基于截至2014年1月15日的湖人比赛。)

    从存储过程返回数据集 (Return a dataset from a Stored Procedure)

    A few discussions went along on how to return a dataset from an SP, which constructs the dataset out of the results from a few repeated calls to another SP.

    进行了一些讨论,讨论如何从SP返回数据集,这从重复调用另一个SP的结果中构造数据集。

    A user may want to know more from our previously created SP that only returns a win/lose streak for one year; thus we can get a table showing the win/lose streaks for all the years in a form like:

    用户可能想从我们之前创建的SP中了解更多信息,该SP仅返回一年的双赢/连败; 因此,我们可以得到一张表格,以表格形式显示多年来所有年份的赢/输条纹:

    YEARWin/LoseStreak
    2013L6
    2012L4
    2011L2
    输赢 条纹
    2013年 大号 6
    2012年 大号 4
    2011年 大号 2

    (Well, a more useful result can be to return the longest win streak and loss streak in a particular season. This requirement can be easily expanded from the previous SP so I will leave it to interested parties to implement. For the purpose of this article, we will stick to the current win/loss streak.)

    (嗯,更有用的结果可能是返回特定季节中最长的连胜和连败。此要求可以从以前的SP轻松扩展,因此我将其留给有兴趣的各方来实施。出于本文的目的,我们将坚持目前的赢/赔率。)

    MySQL SP can only return scalar results (an integer, a string, etc), unless the result is returned by a select ... from ... statement (and it becomes a dataset). The issue here is that the table-form data we want to see does not exist in our current db structure and is constructed from another SP.

    MySQL SP只能返回标量结果(整数,字符串等),除非结果是由select ... from ...语句返回的(并且成为数据集)。 这里的问题是,我们要查看的表形式数据在当前的db结构中不存在,而是由另一个SP构造的。

    To tackle this, we need the help of a temporary table, or if situation allows and requires, a redundant table. Let’s see how we can achieve our target via a temporary table.

    为了解决这个问题,我们需要一个临时表,或者在情况允许的情况下需要一个冗余表。 让我们看看如何通过临时表实现目标。

    First, we will create a second SP as shown below:

    首先,我们将创建第二个SP,如下所示:

    DELIMITER $$
    
    CREATE DEFINER=`root`@`%` PROCEDURE `yearly_streak`()
    begin
        declare cur_year, max_year, min_year int;
    
        select max(year), min(year) from lakers into max_year, min_year;
    
        DROP TEMPORARY TABLE IF EXISTS yearly_streak;
        CREATE TEMPORARY TABLE yearly_streak (season int, streak int, win char(1));
    
        set cur_year=max_year;
    
        year_loop: loop
            if cur_year<min_year then
                leave year_loop;
            end if;
    
            call streak(cur_year, @l, @s);
            insert into yearly_streak values (cur_year, @l, @s);
    
            set cur_year=cur_year-1;
        end loop;
    
        select * from yearly_streak;
        DROP TEMPORARY TABLE IF EXISTS yearly_streak;
    
    END

    A few key things to notice here:

    这里需要注意的一些关键事项:

    1. We determine the max year and min year by selecting from the table lakers;

      我们通过从表中的lakers选择来确定最大年份和最小年份;

    2. We created a temp table to hold the output, with the structure requested by the output (season, streak, win);

      我们创建了一个临时表来保存输出,并具有输出所要求的结构( seasonstreakwin );

    3. In the loop, we first execute our previously created SP, with necessary parameters (call streak(cur_year, @l, @s);), then grab the data returned and insert into the temp table (insert into yearly_streak values (cur_year, @l, @s);).

      在循环中,我们首先使用必要的参数( call streak(cur_year, @l, @s); )执行先前创建的SP,然后获取返回的数据并插入到临时表中( insert into yearly_streak values (cur_year, @l, @s); )。

    4. Finally, we select from the temp table and return the dataset, then do some cleaning (DROP TEMPORARY TABLE IF EXISTS yearly_streak;).

      最后,我们从临时表中选择并返回数据集,然后进行一些清理( DROP TEMPORARY TABLE IF EXISTS yearly_streak; ,则DROP TEMPORARY TABLE IF EXISTS yearly_streak; )。

    To get the results, we create another short PHP script as shown below:

    为了获得结果,我们创建了另一个简短PHP脚本,如下所示:

    <?php
    ... // Here goes the db connection parameters
    
    $cn=new PDO($dsn, $user, $pass);
    
    $res=$cn->query('call yearly_streak')->fetchAll();
    
    foreach ($res as $r)
    {
        echo sprintf("In year %d, the longest W/L streaks is %d %s\n", $r['season'], $r['streak'], $r['win']);
    }

    And the display will be like:

    显示屏将类似于:

    alt

    Please note that the above is a bit different from calling our first SP.

    请注意,以上内容与调用我们的第一个SP有所不同。

    The first SP does not return a dataset but only two parameters. In that case, we use PDO exec then query to fetch the output; while in the second SP, we returned a dataset from the SP, so we use PDO query directly to invoke the call to the SP.

    第一个SP不返回数据集,而仅返回两个参数。 在这种情况下,我们使用PDO exec然后query以获取输出; 而在第二个SP中,我们从SP返回了数据集,因此我们直接使用PDO query来调用对SP的调用。

    Voila! We did it!

    瞧! 我们做到了!

    结论 (Conclusion)

    In this article, we dug further into MySQL stored procedures and took a look at the cursor functionality. We have demonstrated how to fetch scalar data by output parameters (defined as out var_name vartype in the SP declaration) and also fetch a calculated dataset via a temp table. During this process, a few statements otherwise used in stored procedures also surfaced.

    在本文中,我们进一步研究了MySQL存储过程,并研究了游标功能。 我们已经演示了如何通过输出参数(在SP声明中定义为out var_name vartype )获取标量数据,以及如何通过临时表获取计算出的数据集。 在此过程中,还出现了一些其他用于存储过程的语句。

    The official documentation on the syntax of stored procedure and various statements can be found on the MySQL website. To create a stored procedure, please refer to these documents and to understand the statements, please see here.

    有关存储过程语法和各种语句的官方文档可以在MySQL网站上找到。 要创建存储过程,请参考这些文档并了解声明,请参见此处

    Feel free to comment and let us know your thoughts!

    随时发表评论,让我们知道您的想法!

    翻译自: https://www.sitepoint.com/cursors-mysql-stored-procedures/

    mysql 存储过程中游标

    展开全文
  • SqlServer存储过程游标讲解SqlServer存储过程游标讲解
  • 主要介绍了MySQL存储过程中游标循环的跳出和继续操作示例,解决了在MySQL存储过程中循环时执行游标的一个conitnue的操作解决方法,需要的朋友可以参考下
  • 根据一定条件,批量插入和更新mysql数据库的数据--批量插入商户路由关联数据DELIMITER $$USE `100msh_mac`$$DROP PROCEDURE IF EXISTS `批量插入商户路由关联数据`$$CREATE DEFINER=`root`@`%` PROCEDURE `批量...

    根据一定条件,批量插入和更新mysql数据库中的数据

    --批量插入商户路由关联数据

    DELIMITER $$

    USE `100msh_mac`$$

    DROP PROCEDURE IF EXISTS `批量插入商户路由关联数据`$$

    CREATE DEFINER=`root`@`%` PROCEDURE `批量插入商户路由关联数据`()

    BEGIN

    DECLARE v_partner_no VARCHAR(32);

    DECLARE v_partner_id INT(11);

    DECLARE v_sc_pid INT(11);

    DECLARE v_mac_no VARCHAR(32);

    DECLARE v_mac_addr VARCHAR(32);

    DECLARE n_mac_no BIGINT;

    DECLARE n_mac_addr BIGINT;

    DECLARE n_mac_addr_str VARCHAR(32);

    DECLARE done INT;

    #取得商户数据

    DECLARE cur_partnerlist CURSOR

    FOR

    SELECT comp_id, partner_no, sc_pid FROM 100msh_partner.anl_partner;

    SET n_mac_no = 100000000;

    SET n_mac_addr = 1000000000;

    OPEN cur_partnerlist;

    REPEAT

    FETCH cur_partnerlist INTO v_partner_id,v_partner_no,v_sc_pid;

    SET v_mac_no = CONCAT('MAC',v_sc_pid,n_mac_no);

    SET n_mac_addr_str = CONCAT(SUBSTR(n_mac_addr,1,2),':',SUBSTR(n_mac_addr,3,2),':',SUBSTR(n_mac_addr,5,2),':',SUBSTR(n_mac_addr,7,2),':',SUBSTR(n_mac_addr,9,2));

    SET v_mac_addr = CONCAT('CC:',n_mac_addr_str);

    SET n_mac_no = n_mac_no + 1;

    SET n_mac_addr = n_mac_addr + 1;

    #向t_machine_sc_config表中插入商户关联路由的数据

    #insert into t_machine_sc_config(mac_no, partner_no, partner_id, sc_pid, mac_addr, comp_id, is_lock) values('MAC2016000000001','44060430603381',1,4403,'C8:87:18:AB:79:66',1,1);

    INSERT INTO t_machine_sc_config(mac_no, partner_no, partner_id, sc_pid, mac_addr, comp_id, is_lock) VALUES(v_mac_no,v_partner_no,v_partner_id,v_sc_pid,v_mac_addr,1,1);

    UNTIL 0 END REPEAT;

    CLOSE cur_partnerlist;

    END$$

    DELIMITER ;

    --更新商户表

    DELIMITER $$

    USE `100msh_partner`$$

    DROP PROCEDURE IF EXISTS `更新商户表`$$

    CREATE DEFINER=`root`@`%` PROCEDURE `更新商户表`()

    BEGIN

    DECLARE v_partner_no VARCHAR(32);

    DECLARE vpartner_no VARCHAR(32);

    DECLARE v_partner_id VARCHAR(32);

    DECLARE n BIGINT;

    DECLARE partnerid_list CURSOR

    FOR

    SELECT comp_id FROM 100msh_partner.anl_partner WHERE TRIM(partner_no) = '';

    SET vpartner_no = '2015415parno';

    SET n = 10000000;

    OPEN partnerid_list;

    REPEAT

    FETCH partnerid_list INTO v_partner_id;

    SET v_partner_no = CONCAT(vpartner_no,n);

    SET n = n + 1;

    UPDATE 100msh_partner.anl_partner SET partner_no = v_partner_no WHERE comp_id = v_partner_id;

    UNTIL 0 END REPEAT;

    CLOSE partnerid_list;

    END$$

    DELIMITER ;

    展开全文
  • 定义游标(游标就是一个小集合)2. 定义游标变量3. 使用for循环游标declare-- 定义游标c_jobcursor c_job isselect empno, ename, job, sal from emp where job = 'MANAGER';-- 定义游标变量c_rowc_row c_job%rowtype...

    一. 使用for循环游标:

    1. 定义游标(游标就是一个小集合)

    2. 定义游标变量

    3. 使用for循环游标

    declare

    -- 定义游标c_job

    cursor c_job is

    select empno, ename, job, sal from emp where job = 'MANAGER';

    -- 定义游标变量c_row

    c_row c_job%rowtype;

    begin

    -- 循环游标,用游标变量c_row存循环出的值

    for c_row in c_job loop

    dbms_output.put_line(c_row.empno || '-' || c_row.ename || '-' ||

    c_row.job || '-' || c_row.sal);

    end loop;

    end;

    2. fetch游标:

    使用的时候必须明确的打开和关闭

    declare

    --定义游标c_job

    cursor c_job is

    select empno, ename, job, sal from emp where job = 'MANAGER';

    --定义游标变量c_row

    c_row c_job%rowtype;

    begin

    open c_job;

    loop

    --提取一行数据到c_row

    fetch c_job into c_row;

    --判读是否提取到值,没取到值就退出

    exit when c_job%notfound;

    dbms_output.put_line(c_row.empno || '-' || c_row.ename || '-' ||

    c_row.job || '-' || c_row.sal);

    end loop;

    --关闭游标

    close c_job;

    end;

    原文:http://blog.csdn.net/zdp072/article/details/44316719

    展开全文
  • Oracle存储过程游标、函数的详解
  • mysql的存储过程游标 、事务实例详解 下面是自己曾经编写过的mysql数据库存储过程,留作存档,以后用到的时候拿来参考。 其中,涉及到了存储过程游标(双层循环)、事务。 【说明】:代码的注释只针对当时业务...
  • 本文实例讲述了Mysql存储过程中游标的用法。分享给大家供大家参考。具体如下: 1. 批量插入商户路由关联数据: DELIMITER $$ USE `mmm_mac`$$ DROP PROCEDURE IF EXISTS `批量插入商户路由关联数据`$$ CREATE ...
  • mysql存储过程中游标遍历的方法:首先取值,取多个字段;然后遍历数据结束标志,将结束标志绑定到游标,代码为【DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;】。mysql存储过程中游标遍历的方法:...

    mysql存储过程中游标遍历的方法:首先取值,取多个字段;然后遍历数据结束标志,将结束标志绑定到游标,代码为【DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;】。

    a91372c3bfbbbf1e34df318894de012a.png

    mysql存储过程中游标遍历的方法:CREATE DEFINER=`root`@`%` PROCEDURE `updStatus`()

    BEGIN

    DECLARE startTime DATETIME;

    DECLARE endTime DATETIME;

    DECLARE curTime DATETIME;

    DECLARE id VARCHAR(36);

    DECLARE estatus VARCHAR(4);

    -- 遍历数据结束标志

    DECLARE done INT DEFAULT FALSE;

    -- 游标

    DECLARE examIds CURSOR FOR SELECT EXAM_ID FROM t_exam WHERE EXAM_STATUS = 1 or EXAM_STATUS = 2;

    -- 将结束标志绑定到游标

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN examIds;

    -- 遍历

    read_loop: LOOP

    -- 取值 取多个字段

    FETCH NEXT from examIds INTO id;

    IF done THEN

    LEAVE read_loop;

    END IF;

    SELECT EXAM_STATUS INTO estatus FROM t_exam WHERE EXAM_ID = id ;

    IF estatus =1 THEN

    SELECT NOW() INTO curTime;

    SELECT EXAM_START_TIME INTO startTime from t_exam WHERE EXAM_ID = id ;

    SELECT EXAM_END_TIME INTO endTime from t_exam WHERE EXAM_ID = id ;

    IF curTime >= startTime AND endTime > curTime THEN

    UPDATE t_exam SET EXAM_STATUS = 2 WHERE EXAM_ID = id;

    ELSEIF curTime >= endTime THEN

    UPDATE t_exam SET EXAM_STATUS = 3 WHERE EXAM_ID = id;

    END IF;

    ELSE

    SELECT NOW() INTO curTime;

    SELECT EXAM_END_TIME INTO endTime from t_exam WHERE EXAM_ID = id ;

    IF curTime >= endTime THEN

    UPDATE t_exam SET EXAM_STATUS = 3 WHERE EXAM_ID = id;

    END IF;

    END IF;

    END LOOP;

    CLOSE examIds;

    END更多相关免费学习推荐:mysql教程(视频)

    展开全文
  • 最近因为项目需要要写存储过程,以前没咋写过,接触到是接触过,在软通的时候接触过,那是华为的项目那个几个存储过程很大很复杂,也很乱,注释也少,看了个大概。最近一个月,前后也写了七八个简单点的存储过程,也...
  • 本资源结合实例实现一个复杂的存储过程存储过程中有用到游标、临时表、循环、递归等知识,sql文件附有实例数据表创建的sql语句。
  • 用户变量一般以@开头,作用于全局范围局部变量需用 declare 定义格式为 declare 变量名 数据类型 [default value];...同一个存储过程中,一个游标的使用和两个游标的使用是一样的。调用存储过程 call sp_name();...
  • Oracle存储过程中游标的简单使用

    千次阅读 2018-02-06 15:44:16
    初衷: 存储过程中查询语句如何返回多行结果? 我们知道,如果存储过程中查询语句有多行结果输出,会报错: ORA-01422: exact fetch returns ... 本例主要也是用来熟悉存储过程中游标的简单使用方法。案例所涉及
  • 存储过程游标的优缺点

    千次阅读 2018-11-23 17:18:57
    今天咱们就来分析一下储存过程游标的优缺点,比较一下就一步了然了用与不用的选择啦。 存储过程的优缺点 优点  1. 运行速度:对于很简单的sql,存储过程没有什么优势。对于复杂的业务逻辑,因为在存储过程创建...
  • MySQL 存储过程游标的混合使用,也没啥重要的,就是和其他数据库有一些不同而已,作为总结,以后复习
  • CREATE PROCEDURE getUserInfo(in date_day datetime)— — 实例— MYSQL存储过程名为:getUserInfo— 参数为:date_day日期格式:2008-03-08— BEGINdeclare _userName varchar(12); — 用户名declare _chinese int...
  • Java调用oracle存储过程通过游标返回临时表数据 注:本文来源于 < Java调用oracle存储过程通过游标返回临时表数据 > Java调用oracle存储过程通过游标返回临时表数据 项目开发过程中,不可避免的会用到存储过程返回...
  • mysql存储过程游标

    2021-01-26 05:40:22
    游标就类似于迭代器或者指针之类的东西,它指向第一条数据库的记录,每取一次记录则游标向后移动一位2、游标的4个部分1、declare 申明 -- declare 游标名 cursor for select statement2、open 打开 --open 游标名3...
  • MySQL存储过程游标

    千次阅读 2019-02-20 16:30:40
    MySQL5 添加了存储过程的支持。  大多数SQL语句都是针对一个或多个表的单条语句。并非所有的操作都怎么简单。经常会有一个完整的操作需要多条才能完成  存储过程简单来说,就是为以后的使用而保存的一条或多...
  • 存储过程使用游标、临时表实现动态SQL查询 2020.3.24 用能第二周周二上午,任务需求:编写存储过程查询监测设备状态以及目标监测设备状态。(任务完成) 改存储过程包含了大量相关知识,特此记录,以便此后使用! 为...
  • NULL 博文链接:https://gz383.iteye.com/blog/635513
  • 有俩种方法: 一种是声明系统游标,一种是声明自定义游标,然后后面操作一样,参数类型为 in out 或out (1)声明个人系统游标.(推荐) 代码如下: create or replace p_temp_procedure ( cur_arg out sys_refcursor;...
  • 下面是一个订单取消的含2个游标存储过程 set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER PROCEDURE [dbo].[CancelOrderBySystem] AS BEGIN declare /*声明变量*/ @Status varchar(100), –状态 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 90,772
精华内容 36,308
关键字:

存储过程中游标的作用是

友情链接: MFCerzhihua.rar