cursor.md 4.2 KB
Newer Older
M
cursor  
Mars Liu 已提交
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
# 游标

Joe 需要开发一个存储过程 make_trade,从 orders 表

```mysql
create table orders (
    id int primary key auto_increment,
    price decimal(12, 4),
    item_id int,
    amount int
)
```

中,按 id 从小到大加载订单数据,生成交易单,写入 trade 表 

```mysql
create table trade (
    id int primary key auto_increment,
    total decimal(12, 4)
    -- ...
)
```

其中 trade 的 total字段保存了交易单的总金额,这个金额是每一张交易单的所有 orders 的 price 总和,其数值不会超过 20000。

因为撮合交易的逻辑是串行的,Joe决定用游标实现这部分逻辑。下列哪一个选项是对的(选项中仅包含撮合逻辑,不包括完整的存储过程)?

为简单起见,我们忽略交易的详细逻辑,假设 orders 表仅包含 id, price, item_id, amount 四项。

M
Mars Liu 已提交
30 31
<hr/>

M
Mars Liu 已提交
32
点击进入[MySQL实战练习环境](https://mydev.csdn.net/product/pod/new?image=cimg-centos7-skilltreemysql&connect=auto&create=auto&utm_source=skill)
M
Mars Liu 已提交
33 34
* `show databases` 列出所有数据库
* `show tables` 列出所有表
M
Mars Liu 已提交
35

M
cursor  
Mars Liu 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
## 答案

```mysql
create procedure make_trade()
begin
    DECLARE done INT DEFAULT FALSE;
    declare cur_orders cursor for select id, price, item_id, amount from orders order by id limit 1000;
    declare order_id, item_id, amount INT;
    declare price decimal(12, 4);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    open cur_orders;
    trade: LOOP
        fetch cur_orders into order_id, price, item_id, amount;
        if done then
            LEAVE trade;
        end if;
    if @total + @price > 2000 then
        leave trade;
    else
        -- 省略交易逻辑        
    end if;
    END LOOP trade;
    CLOSE cur_orders;
    start transaction;
    -- save trade
    delete from orders where id < order_id;
    commit ;

end;
```

## 选项

### A

```mysql
create procedure make_trade()
begin
    DECLARE done INT DEFAULT FALSE;
    declare cur_orders cursor for select id, price, item_id, amount from orders order by id limit 1000;
    declare order_id, item_id, amount INT;
    declare price decimal(12, 4);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    open cur_orders;
    trade: LOOP
        fetch cur_orders into order_id, price, item_id, amount;
        if done then
            LEAVE trade;
        end if;
    -- 省略交易逻辑
    if @total + @price > 2000 then
        leave trade;
    else
        NEXT cur_orders;
    end if;
    END LOOP trade;
end;
```

### B

```mysql
create procedure make_trade()
begin
    declare cur_orders cursor for select id, price, item_id, amount from orders order by id limit 1000;
    declare order_id, item_id, amount INT;
    declare price decimal(12, 4);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    trade: LOOP
        fetch cur_orders into order_id, price, item_id, amount;
    -- 省略交易逻辑
    END LOOP trade;
    start transaction;
    -- save trade
    delete from orders where id < order_id;
    commit ;
end;
```

### C

```mysql
create procedure make_trade()
begin
    DECLARE done INT DEFAULT FALSE;
    declare cur_orders cursor for select id, price, item_id, amount from orders order by id limit 1000;
    declare order_id, item_id, amount INT;
    declare price decimal(12, 4);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    open cur_orders;
    fetch cur_orders into order_id, price, item_id, amount;
    if done then
        LEAVE cur_orders;
    end if;
    -- 省略交易逻辑
    
end;
```

### D

```mysql
create procedure make_trade()
begin
    DECLARE done INT DEFAULT FALSE;
    declare cur_orders cursor for select id, price, item_id, amount from orders order by id limit 1000;
    declare order_id, item_id, amount INT;
    declare price decimal(12, 4);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    open cur_orders;
    trade: LOOP
        fetch cur_orders into order_id, price, item_id, amount;
        if done then
            LEAVE trade;
        end if;
    -- 省略交易逻辑
        
    END LOOP trade;
    CLOSE cur_orders;
    start transaction;
    -- save trade
    delete from orders where id < order_id;
    commit ;
end;
```