首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

解決導出 Excel 結果與查詢結果不一致:rownum 類型轉換陷阱

     編輯:MySQL 綜合教學

解決導出 Excel 結果與查詢結果不一致:rownum 類型轉換陷阱

現象:SQL 查詢顯示正常,但導出 Excel 後 rownum 列變空或亂碼。根因:JDBC 返回 BIGINT,Java 端以 String 強轉導致 null。

錯誤重現


-- SQL 使用變量生成行號
SELECT CONCAT((@rowNum := @rowNum + 1), '') AS rownum, t.* FROM (...) t;

導出代碼(錯誤版):


Map map = (Map) data.get(i);
HSSFCell cell0 = datarow.createCell(0);
// 錯誤:rownum 實際是 Long,強轉 String 導致 null
HSSFRichTextString t0 = new HSSFRichTextString((String) map.get("rownum") + "");
cell0.setCellValue(t0);

根因分析

  • MySQL 用戶變量 @rowNum 推導類型為 BIGINT。
  • JDBC ResultSet.getObject() 返回 Long。
  • 代碼 (String) map.get("rownum") 嘗試將 Long 強轉為 String,拋出 ClassCastException 被吞噬,最終存入 null。

正確寫法


Map map = (Map) data.get(i);
HSSFCell cell0 = datarow.createCell(0);
// 正確:直接 toString(),支援任意類型(Long、Integer、BigDecimal、String)
Object val = map.get("rownum");
HSSFRichTextString t0 = new HSSFRichTextString(val == null ? "" : val.toString());
cell0.setCellValue(t0);

通用最佳實踐

  1. 統一用 Object 接收,再 val != null ? val.toString() : \"\"。
  2. 避免顯式強轉:(String)、(Integer) 易在類型不匹配時拋異常。
  3. 清理 POI 緩存:大量導出時定期 workbook.write() 並 sheet.flushRows() 防 OOM。
  4. SQL 端顯式轉字串:CAST((@rowNum := @rowNum + 1) AS CHAR) AS rownum,讓 JDBC 直接返回 String,消除類型歧義。

補充:rownum 分頁模式


SELECT * FROM (
  SELECT @rownum := @rownum + 1 AS rownum, t.*
  FROM (SELECT * FROM orders ORDER BY create_time DESC) t,
       (SELECT @rownum := 0) r
) tmp
WHERE rownum BETWEEN 21 AND 30;

MySQL 8.0+ 建議直接用標準 ROW_NUMBER() OVER (ORDER BY create_time DESC) 窗口函數,更簡潔高效。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved