Go客户端中的select查询中的SQL变量未更新

时间:2019-06-27 07:12:52

标签: mysql sql go

我正在SQL中运行以下查询。

SET @thisid=0;
SET @serial=0;

SELECT @serial := IF((@thisid != `places`.`id`), @serial + 1, @serial) as `serial`, @thisid := `places`.`id`, `places`.`id` FROM `places`;

仅当新ID与最后一个ID不同时,变量@serial才基本递增。 在终端中运行这些查询并打印@serial和@thisid的值后,接收到的值为@ thisid ='id6'@ serial = 6。

我在执行代码中执行了此查询:

if _, err = repo.db.ExecContext(ctx, "SET @thisid=0;"); err != nil {
    return
}

if _, err = repo.db.ExecContext(ctx, "SET @serial=0;"); err != nil {
    return
}

rows, err = repo.db.QueryContext(ctx, fmt.Sprintf(
    "SELECT @serial := IF((@thisid != `places`.`id`), @serial + 1, @serial) as `serial`, @thisid := `places`.`id`, `places`.`id` FROM `places`;",
))
if err != nil {
    fmt.Println("error here")
    return
}

if err = repo.db.QueryRow("SELECT @serial").Scan(&that); err != nil {
    return
}

if err = repo.db.QueryRow("SELECT @thisid").Scan(&this); err != nil {
    return
}

在打印@thisid和@serial的值时,收到的@thisid值与将@serial的值接收为0时相同。它似乎没有动态更新。

2 个答案:

答案 0 :(得分:1)

您的查询确实是任意的。 MySQL不保证select中表达式的求值顺序。也不能保证结果集的顺序。

所以,我想你要

select p.*,
       (@rn := if(@id = id, @rn + 1,
                  if(@id := id, 1, 1)
                 )
       ) as serial
from (select p.*
      from places p
      order by p.id
     ) p cross join
     (select @id := 0, @rn := 0) params;

答案 1 :(得分:1)

Go使用连接池,这意味着每个查询可能在不同的连接上发生。像这样的变量的作用域仅限于连接。如果您需要它们在查询之间持续进行,则需要使用事务来确保您保持在同一连接内。