2017-05-26 36 views
0

我有一个存储过程返回一个行列表,我需要过滤返回的结果集(rs)由rs列中的单个值。获取不同的值并过滤ResultSet而不写入循环?

val conn = DriverManager.getConnection(jdbcSqlConn) 

// rs has a column of `Category` 
val rs = conn.createStatement.executeQuery(s"exec getRows $id") 

// Get distinct Category values from rs 
val categories = // distinct value of column Category 
       // How to do it without iterating over the rows? 

// For each category in categories 
//  get the rows filtered by category (where rs.Category = category) 
//  and save it to rsFiltered 
     val writer = new CSVWriter(new FileWriter(s"fileName_$category")) 
     writer.writerAll(rsFiltered, true) // rsFiltered need to have type of ResultSet 

问:

  1. 如何从ResultSet中列得到不同值的列表,而循环?
  2. 请问ResultSet是否有过滤功能?还是需要将其转换为Scala集合?
+0

你正试图在scala中投影命令式的方法,这不是正确的方法。尝试使用slick:这里有一些评论:https://github.com/slick/slick/issues/201在浮油中,你可以评估结果作为scala集合,这会给你很多机会来处理这些集合中的数据包括独特的,订购等 – Pavel

+0

光滑看起来非常好,我一定会在未来使用它。但是,现在我需要尽快解决问题。也许我应该将'ResultSet'转换为Scala集合类型,这样我可以在功能上做到这一点? – ca9163d9

+0

其实,我无法将其转换为其他集合类型。我将需要ResultSet来提供openCsv方法。 – ca9163d9

回答

0

这是一个棘手的问题,因为您需要将输出作为ResultSet的另一个实例。但我认为这是可能的黑客攻击了一点点:

class FilteredResultSet(wrapped: ResultSet, f: ResultSet => Boolean) extends ResultSet { 
    override def next(): Boolean = { 
    var result = wrapped.next() 
    while (result && !f(wrapped)) { 
     result = wrapped.next() 
    } 
    result 
    } 

    override def absolute(x: Int) = wrapped.absolute(x) 
    override def afterLast(): Unit = wrapped.afterLast() 
    // ... delegate all other ResultSet methods ... 
} 

不超惯用的功能斯卡拉,但与Java库集成时的典型。

如果你想在同一时间也收集了一些列的值,你可以这样做:

val categories = scala.mutable.Set.empty[String] 
val filter: ResultSet => Boolean = { rs => 
    val c = rs.getString("Category") 
    categories += c 
    c == someTargetCategory 
} 
val resultRs: ResultSet = new FilteredResultSet(rs, filter) 

再次,有点脏,但它能够完成任务。在处理java库时,我认为对scala功能风格严格要求是很愚蠢的。没有理由不偶尔编写一个while循环或带有副作用的函数。

相关问题