GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — [Bug] sqlserver查询聚合函数出错 · Issue #648 · APIJSON/APIJSON

[Bug] sqlserver查询聚合函数出错 #648

New issue
Copy link
New issue
Copy link
Open
#885
Open
[Bug] sqlserver查询聚合函数出错#648
#885
Copy link
Labels
Config 配置SQLServerhelp wanted请求帮助请求帮助

Description

@fengdu126
fengdu126
opened on Dec 13, 2023
Issue body actions

APIJSON Version/APIJSON 版本号

6.2

Database Type & Version/数据库类型及版本号

sqlserver2012

Environment/环境信息

- JDK/基础库:1.8
- OS/系统:win11

APIAuto Screenshots/APIAuto 请求与结果完整截屏

https://github.com/fengdu126/appokgo/blob/master/c80f2d8b563540fc110e9232b1f3b5d.png

Current Behavior/问题描述

 {
        "Moment": {
             "@column":"max(date):date"
        }
}

返回:{"Moment":{"@column":"max(date):date"},"ok":false,"code":500,"msg":"数据库驱动执行异常SQLException,非 Log.DEBUG 模式下不显示详情,避免泄漏真实模式名、表名等隐私信息"}

log提示:order by 子句 列id无效,因为该列没有包含在聚合函数或group by子句中,

但查max(id)是没有问题的。

Expected Behavior/期望结果

另外希望一条语句能查多个聚合函数,比如: {
        "Moment": {
             "@column":"max(date):date,max(id):id"
        }
}

Any additional comments?/其它补充说明?

No response

Activity

  1. TommyLemon commented on Dec 14, 2023

    @TommyLemon
    TommyLemon
    on Dec 14, 2023
    Member
    More actions

    Oracle, SQL Server, DB2 的分页 OFFSET 必须加 ORDER BY,默认是用 id,如果没有需要重写 getIdKey 返回对应主键名,或者前端传参 "@order":"key" // key / key+ / key-

    https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L1612-L1623
    image

  2. TommyLemon
    added
    SQLServer
    Config 配置
    on Dec 14, 2023
  3. fengdu126 commented on Dec 15, 2023

    @fengdu126
    fengdu126
    on Dec 15, 2023
    Author
    More actions

    Oracle, SQL Server, DB2 的分页 OFFSET 必须加 ORDER BY,默认是用 id,如果没有需要重写 getIdKey 返回对应主键名,或者前端传参 "@order":"key" // key / key+ / key-

    https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L1612-L1623 image

    这个应该不是offset的主键id的问题,就是查询例子里面的Moment表,本来就是有主键id的。

    "Moment": {
    "@column":"max(date):date"
    }

    意思是查询最大日期。
    这条json对应的sqlserver语句应该是: select max(date) as date from Moment

    照理不会牵涉到order by id 的问题,怎么后台会出现:order by 子句 列id无效,因为该列没有包含在聚合函数或group by子句中 这句报错?

  4. fengdu126 commented on Dec 15, 2023

    @fengdu126
    fengdu126
    on Dec 15, 2023
    Author
    More actions

    大概知道什么原因了,是限制行数导致查询出错。

    建议能否完善下,如果包含聚合函数的查询,但又没有group的时候虽然是查全表但实际上永远只会回一行,这种情况就不要在后面加上 ORDER BY "id" OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY 来限制了。

  5. TommyLemon commented on Dec 15, 2023

    @TommyLemon
    TommyLemon
    on Dec 15, 2023
    Member
    More actions

    Oracle, SQL Server, DB2 的分页 OFFSET 必须加 ORDER BY,默认是用 id,如果没有需要重写 getIdKey 返回对应主键名,或者前端传参 "@order":"key" // key / key+ / key-

    https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L1612-L1623 image

    那就需要调整下这里的逻辑,判断 RequestMethod.isGetMethod(method, true) 时,才拼接 FETCH 语句

  6. fengdu126 commented on Dec 17, 2023

    @fengdu126
    fengdu126
    on Dec 17, 2023
    Author
    More actions

    Oracle, SQL Server, DB2 的分页 OFFSET 必须加 ORDER BY,默认是用 id,如果没有需要重写 getIdKey 返回对应主键名,或者前端传参 "@order":"key" // key / key+ / key-
    https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L1612-L1623 image

    那就需要调整下这里的逻辑,判断 RequestMethod.isGetMethod(method, true) 时,才拼接 FETCH 语句
    不知道怎么改,大佬能否修复下这个bug

  7. TommyLemon commented on Dec 19, 2023

    @TommyLemon
    TommyLemon
    on Dec 19, 2023
    Member
    More actions

    外层 if 加个 method 的判断就行,我暂时还没时间处理
    https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L1612-L1623
    image

    如果你已经知道问题所在、怎么解决,请直接 提交 Pull Request 为社区做贡献,非常感谢。
    开发者也是人,也需要工作、休息、恋爱、陪伴家人、走亲会友等,也有心情不好和身体病痛,
    往往没有额外的时间精力顾及一些小问题,请理解和支持,开源要大家参与贡献才会更美好~
    少数个人的热情终有被耗尽的一天,只有大家共同建设和繁荣社区,才能让开源可持续发展!
    #406
    image
    https://github.com/Tencent/APIJSON/blob/master/CONTRIBUTING.md#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%80%E5%AE%9A%E8%A6%81%E8%B4%A1%E7%8C%AE%E4%BB%A3%E7%A0%81

  8. TommyLemon
    added
    help wanted请求帮助请求帮助
    on Dec 19, 2023
  9. fengdu126 commented on Dec 21, 2023

    @fengdu126
    fengdu126
    on Dec 21, 2023
    Author
    More actions

    OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY

    不是这里改order by的问题,而是要去掉 OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY才行,因为 select max(date) as date from Moment 当没有group by的时候永远只会返回一行,这种情况不能再拼接limitstring了。

  10. TommyLemon commented on Dec 23, 2023

    @TommyLemon
    TommyLemon
    on Dec 23, 2023
    Member
    More actions

    加了 GROUP BY 就很可能不只一行了,在没法自动判断的前提下只能统一加上。

    https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L2576-L2591
    image

    如果想不拼接 FETCH 语句,可以前端在 [] 内传参 count: 1,并且后端改下 getLimitString 代码,

    boolean isTSQL = isOracle() || isSQLServer() || isDb2();
    if (isTSQL && count == 1) {
      return "";
    }

    "@column":"max(date):date,max(id):id" 写法不符合 APIJSON 语法,必须用 ; 分号分隔 SQL 函数。
    https://github.com/Tencent/APIJSON/blob/master/Document.md
    image

    image

    http://apijson.cn/api/?send=true&type=JSON&url=http%3A%2F%2Fapijson.cn%3A8080%2Fget&json={%22User%22:{%22@column%22:%22max(date)%3Adate%3Bmax(id)%3Aid%22}}

    image http://apijson.cn/api/?send=true&type=JSON&url=http%3A%2F%2Fapijson.cn%3A8080%2Fget&json={%22[]%22:{%22Comment%22:{%22@column%22:%22max(date)%3Adate%3Bmax(id)%3Aid%22,%22@order%22:%22date-%2Cid%2B%22}},%22@explain%22:true}
  11. fengdu126 commented on Dec 28, 2023

    @fengdu126
    fengdu126
    on Dec 28, 2023
    Author
    More actions

    通过判断[]里面的count是否等于某个特定数字虽然是可以解决,但最好还是能不加[]和count,能自动判断是否需要加LimitString

  12. TommyLemon commented on Dec 28, 2023

    @TommyLemon
    TommyLemon
    on Dec 28, 2023
    Member
    More actions

    确实这样更好,应该可以像 Oracle 一样通过 ROW_NUM 替代 FETCH 来解决,相关判断 isOracle 的地方改成 (isOracle || isSQLServer)

  13. TommyLemon commented on Dec 28, 2023

    @TommyLemon
    TommyLemon
    on Dec 28, 2023
    Member
    More actions

    不需要分页的地方,也可以改用拼接 TOP 语句来简单解决

  14. fengdu126 commented on Dec 29, 2023

    @fengdu126
    fengdu126
    on Dec 29, 2023
    Author
    More actions

    不需要分页的地方,也可以改用拼接 TOP 语句来简单解决

    这个可以有,一些场合是不需要分页的,能否跟@column一样加上@top关键词,表示只select前面n条记录,有了top就不用强制加LimitString和order by了

  15. TommyLemon commented on Dec 29, 2023

    @TommyLemon
    TommyLemon
    on Dec 29, 2023
    Member
    More actions

    不需要加 @top 关键词,只要前端在 [] 内传参 count 并且 page 不是正数,或者只是查单个对象(count = 1),都直接对应转成 getSQL 方法内的 SELECT TOP $count,至于 getLimitString 就直接返回空字符串。

  16. fengdu126 commented on Dec 30, 2023

    @fengdu126
    fengdu126
    on Dec 30, 2023
    Author
    More actions

    不需要加 @top 关键词,只要前端在 [] 内传参 count 并且 page 不是正数,或者只是查单个对象(count = 1),都直接对应转成 getSQL 方法内的 SELECT TOP $count,至于 getLimitString 就直接返回空字符串。

    试了不行,count和page的值都必须大于等于0,提示page值不合法,必须是0-100

  17. TommyLemon commented on Jan 1, 2024

    @TommyLemon
    TommyLemon
    on Jan 1, 2024
    Member
    More actions

    怎么会?只有 page == 0 时采用 TOP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Config 配置SQLServerhelp wanted请求帮助请求帮助

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.