当前位置:   article > 正文

达梦数据库使用常见错误及解决方案(MySQL)

达梦数据库使用常见错误及解决方案(MySQL)

[-4080]: 不是 group by 表达式

【例子】

  1. select ri.*,count(bd.id) bindDeviceCount
  2. from room_ip ri left join bids_device bd on ri.name = bd.room_name

【问题原因】

  • GROUP BY 和 ORDER BY 一起使用时,ORDER BY 要在 GROUP BY 的后面。
  • 在 select 需要查询的语句中选中的字段,必须出现在 GROUP BY 子句中。

【解决方法】

若不想修改 SQL 语句,可以通过以下方法解决: 方法 1:修改 dm.ini 的 compatible_mode 参数为 4,来兼容 MySQL 语法,修改参数后需要重启数据库服务。 方法 2: 非 mysql 兼容模式下(即 COMPATIBLE_MODE 不等于 4),修改 GROUP_OPT_FLAG(动态会话级)参数包含 1 取值,即支持查询项不是 GROUP BY 表达式。

alter  system set 'GROUP_OPT_FLAG'=1 both;

 使用Map接受数据列名会变成大写

 【解决方法】:加上columnNameUpperCase=false配置,如下

        jdbc:dm://192.168.0.96:5236?columnNameUpperCase=false

 【注意事项】:有些关键词还是会出现大写的情况,比如count,enable,可以加上双引号的方式来解决,如下:

在DM8上对大字段类型列进行排序、分组等操作时,会报错-2685:试图在blob或者clob列上排序或比较 

【例子】:C1为大字段

  • SELECT ID,C1 FROM T ORDER BY C1;
  • SELECT ID,COUNT(*) FROM T GROUP BY ID;(虽然没有使用到大字段C1,但是因为表中含有大字段,分组的时候依然会报错)

【解决方法】

将数据库参数ENABLE_BLOB_CMP_FLAG设置为1后,数据库支持DISTINCT、ORDER BY、分析函数和集函数支持对大字段进行处理。

【注意事项】

该参数并不能支持GROUP BY 对大字段进行处理。即不能 GROUP BY C1,正常来说也不会对TEXT字段进行分组

 ON DUPLICATE KEY UPDATE语法的改写

【mysql】

  1. insert into "user"(third_id,third_status,mk_time,flag,card_type,valid_start_time,valid_end_time,user_name,
  2. organization,department,face_photo,access_card,type,can_access,enable_app,status,register_code,create_time,update_time,tel_extension,card_id)
  3. values
  4. <foreach collection="userList" index="index" item="item" separator=",">
  5. (#{item.thirdId}, #{item.thirdStatus},#{item.mkTime},#{item.flag},#{item.cardType},#{item.validStartTime},
  6. #{item.validEndTime},#{item.userName},#{item.organization},
  7. #{item.department}, #{item.facePhoto},#{item.accessCard},0,#{item.canAccess},0,0,#{item.registerCode},#{item.createTime},#{item.updateTime},#{item.telExtension},#{item.cardId})
  8. </foreach>
  9. ON DUPLICATE KEY UPDATE
  10. third_status = values(third_status),
  11. mk_time = values(mk_time),
  12. flag = values(flag),
  13. card_type = values(card_type),
  14. valid_start_time = values(valid_start_time),
  15. valid_end_time = values(valid_end_time),
  16. user_name = values(user_name),
  17. organization = values(organization),
  18. department = values(department),
  19. face_photo = values(face_photo),
  20. access_card = values(access_card),
  21. update_time = values(update_time),
  22. tel_extension = values(tel_extension),
  23. card_id=values(card_id);

【dm】

  1. MERGE INTO "user" T1
  2. USING (
  3. <foreach collection="userList" item="item" index="index" separator="UNION ALL">
  4. SELECT
  5. #{item.thirdId} thirdId, #{item.thirdStatus} thirdStatus,#{item.mkTime} mkTim,#{item.flag} flag,#{item.cardType} cardType,#{item.validStartTime} validStartTime,
  6. #{item.validEndTime} validEndTime,#{item.userName} userName,#{item.organization} organization,
  7. #{item.department} department, #{item.facePhoto} facePhoto,#{item.accessCard} accessCard,0 type,#{item.canAccess} canAccess,0 enableApp,
  8. 0 status,#{item.registerCode} registerCode,#{item.createTime} createTime,#{item.updateTime} updateTime,#{item.telExtension} telExtension,#{item.cardId} cardId
  9. FROM dual
  10. </foreach>
  11. ) T2 ON (T1.third_id = T2.thirdId )
  12. WHEN NOT MATCHED THEN INSERT(third_id,third_status,mk_time,flag,card_type,valid_start_time,valid_end_time,user_name,
  13. organization,department,face_photo,access_card,type,can_access,enable_app,status,register_code,create_time,update_time,tel_extension,card_id) VALUES
  14. (T2.thirdId, T2.thirdStatus, T2.mkTim, T2.flag, T2.cardType, T2.validStartTime, T2.validEndTime, T2.userName, T2.organization, T2.department, T2.facePhoto, T2.accessCard,
  15. T2.type, T2.canAccess, T2.enableApp, T2.status, T2.registerCode, T2.createTime, T2.updateTime, T2.telExtension, T2.cardId
  16. )
  17. WHEN MATCHED THEN UPDATE
  18. SET
  19. T1.third_status = T2.thirdStatus,
  20. T1.mk_time = T2.mkTim,
  21. T1.flag = T2.flag,
  22. T1.card_type = T2.cardType,
  23. T1.valid_start_time = T2.validStartTime,
  24. T1.valid_end_time = T2.validEndTime,
  25. T1.user_name = T2.userName,
  26. T1.organization = T2.organization,
  27. T1.department = T2.department,
  28. T1.face_photo = T2.facePhoto,
  29. T1.access_card = T2.accessCard,
  30. T1.update_time = T2.updateTime,
  31. T1.tel_extension = T2.telExtension,
  32. T1.card_id=T2.cardId;

  GROUP_CONCAT改写为LISTAGG

【mysql】

  1. SELECT
  2. location_id,
  3. GROUP_CONCAT( personnel_id ORDER BY snap_time DESC ) ids,
  4. COUNT(personnel_id) count
  5. FROM
  6. user_access_record
  7. WHERE
  8. door_no = 1
  9. GROUP BY
  10. location_id

【dm】

  1. SELECT
  2. location_id,
  3. LISTAGG( personnel_id,',')WITHIN GROUP(ORDER BY snap_time DESC) ids,
  4. COUNT(personnel_id) count
  5. FROM
  6. user_access_record
  7. WHERE
  8. door_no = 1
  9. GROUP BY
  10. location_id
  1. SELECT
  2. pr.id,
  3. pr.project_no,
  4. LISTAGG(DISTINCT eir.expert_name,',') stockName,
  5. LISTAGG(DISTINCT eir2.expert_name,',') expertName
  6. FROM
  7. project_sync_record pr
  8. left join expert_sync_record eir
  9. on eir.expert_type = '采购人' and pr.project_no = eir.project_no and TO_CHAR (pr.actual_start_time, 'yyyy-mm-dd') = eir.create_date
  10. left join expert_sync_record eir2
  11. on eir2.expert_type = '专家' and pr.project_no = eir2.project_no and eir.create_date = eir2.create_date
  12. group by pr.project_no,pr.meeting_type

分组后按组里某个字段排序取最大一条记录的其他字段

【mysql】注意mysql8.0之前是不支持该语法的,顾这里不列例子

【dm】按user_id分组,并取check_time最大的一条记录的result

  1. SELECT
  2. "user".id,
  3. "user".user_name name,
  4. "user".phone tel,
  5. "user".photo_url photoUrl,
  6. ah.check_time checkTime,
  7. ah.result "result"
  8. FROM
  9. ( SELECT id, row_number() over ( PARTITION BY user_id ORDER BY check_time DESC ) AS f_part FROM alarm_handler WHERE record_id = #{id} ) t
  10. INNER JOIN alarm_handler ah ON t.id = ah.id
  11. LEFT JOIN "user" ON ah.user_id = "user".id
  12. WHERE
  13. t.f_part = 1

达梦建表时主键默认是非聚集索引

达梦建表时主键默认是非聚集索引,默认聚集索引键是 ROWID,即记录默认以 ROWID 在页面中排序。ROWID 是 B 树为记录生成的逻辑递增序号,表上不同记录的 ROWID 是不一样的,并且最新插入的记录 ROWID 最大。很多情况下,以 ROWID 建的默认聚集索引并不能提高查询速度,因为实际情况下很少人根据 ROWID 来查找数据。

如果想和mysql一样,建表时主键即是聚集索引,可以参考如下:

在 dm.ini 配置文件中,可以通过指定 PK_WITH_CLUSTER 使表中的主键为聚集主键。默认情况下,PK_WITH_CLUSTER 为 0,即建表时指定的主键是非聚集主键;若为 1,则主键为聚集主键。

但是有两个注意点:

1.聚集索引只能有一个

2.聚集索引不能和大字段(比如TEXT)同时存在

所以要不要聚集索引还是看实际情况,这一点是和mysql不同的。

关联查询排序索引失效

不知道为什么关联之后达梦索引就变得很不智能,需要用hint提示它该怎么用索引,mysql这方面会好很多

   select /*+ TOP_ORDER_OPT_FLAG(1) */pm.*, 
          "user".organization guikou_organization, 
          "user".department guikou_department, 
          "user".phone guikou_phone 
     from park_manage pm 
LEFT JOIN "user" 
       ON pm.guikou_id = "user".id
 order by pm.create_time desc limit 20;

/*+ TOP_ORDER_OPT_FLAG(1) */的意思参考

查询所有表所占的大小及所在空间


SELECT 
A.OWNER AS "模式",
A.SEGMENT_NAME AS "表名",
A.BYTES/1024 AS "大小(KB)",
A.TABLESPACE_NAME AS "所属表空间",
B.COMMENTS AS "表注释" 
FROM DBA_SEGMENTS A,DBA_TAB_COMMENTS B 
WHERE A.OWNER=B.OWNER 
AND A.SEGMENT_NAME = B.TABLE_NAME 
--AND A.OWNER='SYSDBA' 
ORDER BY SEGMENT_NAME ASC;
 


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/880928
推荐阅读
相关标签
  

闽ICP备14008679号