Browse Source

解决 ”ORA-01792: 表或视图中的最大列数为 1000“的问题

sunyj 8 years ago
parent
commit
9bd9b59e30
1 changed files with 22 additions and 1 deletions
  1. 22 1
      src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

+ 22 - 1
src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

@@ -757,7 +757,28 @@ public class PrintServiceImpl implements PrintService {
 	 * @throws SQLException
 	 */
 	private int getCount(Connection connection, String sql) throws SQLException {
-		sql = "select count(1) from (" + sql + ")";
+		// 如果直接在 sql 外用 count(1) 统计数目,当关联表多时,可能会出现错误
+		// ORA-01792: 表或视图中的最大列数为 1000
+		// 报错主要发生在 select * 的情况下,但是不能这样判断,因为可能存在 select tt.*, pi_id from
+		// purchase t left join 这样的情况,很难区分
+		// 因此 1. 对于普通 sql ,将 select 后的字段改为 count(1)
+		// 2. 而最外层含有 group by 的 sql ,直接改为 count(1) 可能得到不止一行,结果也并非实际行数。再加上 group
+		// by 的结果列数一般很小,所以可以在外面使用 count(1) ,一般不会超出 1000 行
+		String lowerSql = sql.toLowerCase();
+		if (!lowerSql.matches("[\\s\\S]+?group[\\s]+?by[\\s]+?[^)]+?")) {
+			String regex = "[\\s\\S]+?from";
+			Pattern pattern = Pattern.compile(regex);
+			Matcher matcher = pattern.matcher(lowerSql);
+			if (matcher.find()) {
+				int start = matcher.start();
+				int end = matcher.end();
+				sql = sql.substring(0, start) + "select count(1) from" + sql.substring(end);
+			} else {
+				throw new IllegalStateException("sql 解析错误:未发现第一个 from");
+			}
+		} else {
+			sql = "select count(1) from (" + sql + ")";
+		}
 		PreparedStatement preparedStatement = connection.prepareStatement(sql);
 		ResultSet resultSet = preparedStatement.executeQuery();
 		resultSet.next();