didi / gendry

a golang library for sql builder
Apache License 2.0
1.6k stars 191 forks source link

buildInsert 对于mysql 5.7升级mysql 8.0 , 用到mysql 8.0关键词的人不友好, #149

Open xiangshang190823 opened 4 weeks ago

xiangshang190823 commented 4 weeks ago

mysql 5.7升级到8.0,某些表加了8.0的关键词作为字段,该框架框架 tag不支持增加反括号这个处理, 这个表的model中的rank字段如何加反引号处理

type TBBestFriendRank struct {

ID            int64  `ddb:"id" json:"id" form:"id"`                                        //  自增主键

UserID        int64  `ddb:"user_id" json:"user_id" form:"user_id"`                         //  用户id

FriendUserID  int64  `ddb:"friend_user_id" json:"friend_user_id" form:"friend_user_id"`    //  挚友id

SouvenirID    int64  `ddb:"souvenir_id" json:"souvenir_id" form:"souvenir_id"`             //  信物id

Rank          int64  `ddb:"rank" json:"rank" form:"rank"`                                  //  排名,从1开始

Score         int64  `ddb:"score" json:"score" form:"score"`                               //  周期内分数

RankStartDate string `ddb:"rank_start_date" json:"rank_start_date" form:"rank_start_date"` //  榜单开始时间

RankType      int64  `ddb:"rank_type" json:"rank_type" form:"rank_type"`                   //  榜单类型:0周榜,1月榜

CreateTime    int64  `ddb:"create_time" json:"create_time" form:"create_time"`             //  创建时间

} 建议可以在 buildInsert 等函数中,可以给字段加上反引号,去做插入,或者查询,这样更为通用一些,否则一些特殊case,处理不了

caibirdme commented 3 weeks ago

给个你实际使用的code example?

xiangshang190823 commented 3 weeks ago

实际case: 我们用的线下是mysql 8.0 线上mysql 5.7版本,目前去用该库的sqlbuilder 查询rank字段,会报错。

xiangshang190823 commented 3 weeks ago

实际case: 我们用的线下是mysql 8.0 线上mysql 5.7版本,目前去用该库的sqlbuilder 去组装sql语句,查询rank字段,会报错。 select rank from testA; 5.7版本,可以正常查询出数值; 8.0版本。会报错, ![Uploading 0d656abbf4b5266b2b4d5caa5.png…]()

xiangshang190823 commented 3 weeks ago

/**

type MallBannerDB struct { ID int64 json:"id" ddb:"id" // 自增 id Photo string json:"photo" ddb:"photo" // 图片 Rank int64 json:"rank" ddb:"rank" // 排序 AndroidURL string json:"android_url" ddb:"android_url" // 安卓跳转地址 IOSURL string json:"ios_url" ddb:"ios_url" // ios跳转地址 Status int64 json:"status" ddb:"status" // 状态 状态:0-未上线,1-已上线 Device string json:"device" ddb:"device" // 设备类型:all-全部, android-安卓, ios-苹果 StartTime int64 json:"start_time" ddb:"start_time" // 开始时间 EndTime int64 json:"end_time" ddb:"end_time" // 结束时间 MinAppVersion string json:"min_app_version" ddb:"min_app_version" // 最低版本 MaxAppVersion string json:"max_app_version" ddb:"max_app_version" // 最高版本 CreateTime int64 json:"create_time" ddb:"create_time" // 创建时间 UpdateTime int64 json:"update_time" ddb:"update_time" // 更新时间 }

banner

这个数据库有但是查询获取不到值

code_banner
xiangshang190823 commented 3 weeks ago

以下两个语句就是反引号的差异,但是在mysql 5.7旧版本引用了8.0定义的关键字作为字段的话,gendry构建出的sql语句,则会报错。 当前框架构建的sql语句 SELECT FROM tb_mall_banner WHERE rank = ? 目前看gorm构建的语句其实用反引号避免了这个case,故建议加上这个反引号的处理更优雅&& 能兼容更多样的情况 gorm构建的语句 SELECT FROM tb_mall_banner WHERE tb_mall_banner.rank = ?

xiangshang190823 commented 3 weeks ago

以下两个语句就是反引号的差异,但是在mysql 5.7旧版本引用了8.0定义的关键字作为字段的话,gendry构建出的sql语句,则会报错。 当前框架构建的sql语句 SELECT FROM tb_mall_banner WHERE rank = ? 目前看gorm构建的语句其实用反引号避免了这个case,故建议加上这个反引号的处理更优雅&& 能兼容更多样的情况 gorm构建的语句 SELECT FROM tb_mall_banner WHEREtb_mall_banner.rank = ?

xiangshang190823 commented 3 weeks ago

tb_mall_banner 和rank中间的反引号被消除了,展示不出来 ![Uploading sql.png…]()

xiangshang190823 commented 3 weeks ago
sql
caibirdme commented 3 weeks ago

你是说构建出来的sql语句遇到数据库关键字有问题对吧…我看你一开始的描述还以为是无法Scan

你们是基于gendry之上封装了一层吗?gendry的struct tag只用于Scan,没有用于生成sql语句。 你可以如下

where["`rank`"]=xxx

去规避这个问题。

没有默认加"`"符号,是因为有的用户希望 where["函数名(col)"]=xx,如果要默认加"`",则需要对map key做一定的语法解析才行,那样太复杂了没必要

xiangshang190823 commented 3 weeks ago

我们是基于gendry之上封装了一层,where["rank"]=xxx可以规避查询问题,但是insert 插入语句遇到关键词也有问题

xiangshang190823 commented 3 weeks ago

例如,INSERT INTO tb_mall_banner ( photo, rank, android_url, ios_url, status, start_time, end_time, op_user, min_app_version, max_app_version, create_time, update_time, device) VALUES (296, 'voiceroom/banner/2024-02-23/146591d6-96ae-427f-a0bd-e493f85daa7a.png', 4, ‘a’, ‘b’, 1, 1708617600, 1712851200, ‘a’, '', '', 0, 1708675457, 'all'); 8.0版本由于有rank关键词的字段的存在,会发生报错,手写sql是能解决这个问题,但是第一不方便,第二批量插入操作,用手写拼装的方式也不是很优雅

xiangshang190823 commented 3 weeks ago

如果where 不加反引号也能行,但是insert 也没有的话,这个就很囧,不太好实现 我当前的case,或者用当前框架还有没有别的方式去实现

caibirdme commented 3 weeks ago

Got it,如果要解决可能需要拓展一下API,比如提供一个自定义hook,你可以自己对字段名按需做二次修改

xiangshang190823 commented 3 weeks ago

目前形态是没法做到是吗?没有比较好的实现思路,除了用原生的sql语句去执行

caibirdme commented 3 weeks ago

给Build方法增加Option参数,比如: BuildInsert(...., WithColModify(your_func))

func your_func(col string) string {
  if col == "rank" {
    return "`rank`"
  }
}