cursor.md 3.9 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 30 31 32 33 34 35 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
# 游标

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 四项。

## 答案

```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;
```